diff --git a/Copyright b/Copyright
index c058f02..f76a86d 100644
--- a/Copyright
+++ b/Copyright
@@ -1,6 +1,6 @@
-Except where otherwise noted in the source code (e.g. the files dict.c,
-list.c and the trio files, which are covered by a similar licence but
-with different Copyright notices) all the files are:
+Except where otherwise noted in the source code (e.g. the files dict.c and
+list.c, which are covered by a similar licence but with different Copyright
+notices) all the files are:
Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved.
diff --git a/HTMLparser.c b/HTMLparser.c
index ea6a4f2..3be7464 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -58,25 +58,9 @@ static void htmlParseComment(htmlParserCtxtPtr ctxt);
* Handle a redefinition of attribute error
*/
static void
-htmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
+htmlErrMemory(xmlParserCtxtPtr ctxt)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL) {
- ctxt->errNo = XML_ERR_NO_MEMORY;
- ctxt->instate = XML_PARSER_EOF;
- ctxt->disableSAX = 1;
- }
- if (extra)
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
- else
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
- NULL, NULL, 0, 0, "Memory allocation failed\n");
+ xmlCtxtErrMemory(ctxt);
}
/**
@@ -93,18 +77,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
htmlParseErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar *str1, const xmlChar *str2)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_HTML, error,
- XML_ERR_ERROR, NULL, 0,
- (const char *) str1, (const char *) str2,
- NULL, 0, 0,
- msg, str1, str2);
- if (ctxt != NULL)
- ctxt->wellFormed = 0;
+ xmlCtxtErr(ctxt, NULL, XML_FROM_HTML, error, XML_ERR_ERROR,
+ str1, str2, NULL, 0, msg, str1, str2);
}
/**
@@ -120,16 +94,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
htmlParseErrInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, int val)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_HTML, error,
- XML_ERR_ERROR, NULL, 0, NULL, NULL,
- NULL, val, 0, msg, val);
- if (ctxt != NULL)
- ctxt->wellFormed = 0;
+ xmlCtxtErr(ctxt, NULL, XML_FROM_HTML, error, XML_ERR_ERROR,
+ NULL, NULL, NULL, val, msg, val);
}
/************************************************************************
@@ -161,7 +127,7 @@ htmlnamePush(htmlParserCtxtPtr ctxt, const xmlChar * value)
tmp = xmlRealloc((xmlChar **) ctxt->nameTab,
newSize * sizeof(ctxt->nameTab[0]));
if (tmp == NULL) {
- htmlErrMemory(ctxt, NULL);
+ htmlErrMemory(ctxt);
return (-1);
}
ctxt->nameTab = tmp;
@@ -219,7 +185,7 @@ htmlNodeInfoPush(htmlParserCtxtPtr ctxt, htmlParserNodeInfo *value)
ctxt->nodeInfoMax *
sizeof(ctxt->nodeInfoTab[0]));
if (ctxt->nodeInfoTab == NULL) {
- htmlErrMemory(ctxt, NULL);
+ htmlErrMemory(ctxt);
return (0);
}
}
@@ -289,13 +255,16 @@ htmlNodeInfoPop(htmlParserCtxtPtr ctxt)
#define CUR_PTR ctxt->input->cur
#define BASE_PTR ctxt->input->base
-#define SHRINK if ((ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
- (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
- xmlParserShrink(ctxt)
+#define SHRINK \
+ if ((!PARSER_PROGRESSIVE(ctxt)) && \
+ (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
+ (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
+ xmlParserShrink(ctxt);
-#define GROW if ((ctxt->progressive == 0) && \
- (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
- xmlParserGrow(ctxt)
+#define GROW \
+ if ((!PARSER_PROGRESSIVE(ctxt)) && \
+ (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
+ xmlParserGrow(ctxt);
#define SKIP_BLANKS htmlSkipBlankChars(ctxt)
@@ -304,14 +273,14 @@ htmlNodeInfoPop(htmlParserCtxtPtr ctxt)
#define CUR (*ctxt->input->cur)
#define NEXT xmlNextChar(ctxt)
-#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
+#define RAW (*ctxt->input->cur)
#define NEXTL(l) do { \
if (*(ctxt->input->cur) == '\n') { \
ctxt->input->line++; ctxt->input->col = 1; \
} else ctxt->input->col++; \
- ctxt->token = 0; ctxt->input->cur += l; \
+ ctxt->input->cur += l; \
} while (0)
/************
@@ -343,6 +312,7 @@ htmlNodeInfoPop(htmlParserCtxtPtr ctxt)
static xmlChar *
htmlFindEncoding(xmlParserCtxtPtr ctxt) {
const xmlChar *start, *cur, *end;
+ xmlChar *ret;
if ((ctxt == NULL) || (ctxt->input == NULL) ||
(ctxt->input->flags & XML_INPUT_HAS_ENCODING))
@@ -374,7 +344,10 @@ htmlFindEncoding(xmlParserCtxtPtr ctxt) {
cur++;
if (cur == start)
return(NULL);
- return(xmlStrndup(start, cur - start));
+ ret = xmlStrndup(start, cur - start);
+ if (ret == NULL)
+ htmlErrMemory(ctxt);
+ return(ret);
}
/**
@@ -397,23 +370,11 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
unsigned char c;
unsigned int val;
- if (ctxt->instate == XML_PARSER_EOF)
- return(0);
-
- if (ctxt->token != 0) {
- *len = 0;
- return(ctxt->token);
- }
-
- if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) {
+ if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)
xmlParserGrow(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- return(0);
- }
if ((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) {
xmlChar * guess;
- xmlCharEncodingHandlerPtr handler;
/*
* Assume it's a fixed length encoding (1) with
@@ -421,13 +382,18 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
* HTML constructs only use < 128 chars
*/
if (*ctxt->input->cur < 0x80) {
- *len = 1;
- if ((*ctxt->input->cur == 0) &&
- (ctxt->input->cur < ctxt->input->end)) {
- htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
- "Char 0x%X out of allowed range\n", 0);
- return(' ');
+ if (*ctxt->input->cur == 0) {
+ if (ctxt->input->cur < ctxt->input->end) {
+ htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
+ "Char 0x%X out of allowed range\n", 0);
+ *len = 1;
+ return(' ');
+ } else {
+ *len = 0;
+ return(0);
+ }
}
+ *len = 1;
return(*ctxt->input->cur);
}
@@ -438,18 +404,7 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
if (guess == NULL) {
xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
} else {
- handler = xmlFindCharEncodingHandler((const char *) guess);
- if (handler != NULL) {
- /*
- * Don't use UTF-8 encoder which isn't required and
- * can produce invalid UTF-8.
- */
- if (!xmlStrEqual(BAD_CAST handler->name, BAD_CAST "UTF-8"))
- xmlSwitchToEncoding(ctxt, handler);
- } else {
- htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
- "Unsupported encoding %s", guess, NULL);
- }
+ xmlSwitchEncodingName(ctxt, (const char *) guess);
xmlFree(guess);
}
ctxt->input->flags |= XML_INPUT_HAS_ENCODING;
@@ -516,12 +471,16 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
}
return(val);
} else {
- if ((*ctxt->input->cur == 0) &&
- (ctxt->input->cur < ctxt->input->end)) {
- htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
- "Char 0x%X out of allowed range\n", 0);
- *len = 1;
- return(' ');
+ if (*ctxt->input->cur == 0) {
+ if (ctxt->input->cur < ctxt->input->end) {
+ htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
+ "Char 0x%X out of allowed range\n", 0);
+ *len = 1;
+ return(' ');
+ } else {
+ *len = 0;
+ return(0);
+ }
}
/* 1-byte code */
*len = 1;
@@ -529,20 +488,7 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
}
encoding_error:
- {
- char buffer[150];
-
- if (ctxt->input->end - ctxt->input->cur >= 4) {
- snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- ctxt->input->cur[0], ctxt->input->cur[1],
- ctxt->input->cur[2], ctxt->input->cur[3]);
- } else {
- snprintf(buffer, 149, "Bytes: 0x%02X\n", ctxt->input->cur[0]);
- }
- htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
- "Input is not proper UTF-8, indicate encoding !\n",
- BAD_CAST buffer, NULL);
- }
+ xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
if ((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0)
xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
@@ -2035,7 +1981,7 @@ static const htmlEntityDesc html40EntitiesTable[] = {
buffer##_size *= 2; \
tmp = (xmlChar *) xmlRealloc(buffer, buffer##_size); \
if (tmp == NULL) { \
- htmlErrMemory(ctxt, "growing buffer\n"); \
+ htmlErrMemory(ctxt); \
xmlFree(buffer); \
return(NULL); \
} \
@@ -2065,6 +2011,14 @@ htmlEntityLookup(const xmlChar *name) {
return(NULL);
}
+static int
+htmlCompareEntityDesc(const void *vkey, const void *vdesc) {
+ const unsigned *key = vkey;
+ const htmlEntityDesc *desc = vdesc;
+
+ return((int) *key - (int) desc->value);
+}
+
/**
* htmlEntityValueLookup:
* @value: the entity's unicode value
@@ -2077,17 +2031,14 @@ htmlEntityLookup(const xmlChar *name) {
*/
const htmlEntityDesc *
htmlEntityValueLookup(unsigned int value) {
- unsigned int i;
+ const htmlEntityDesc *desc;
+ size_t nmemb;
- for (i = 0;i < (sizeof(html40EntitiesTable)/
- sizeof(html40EntitiesTable[0]));i++) {
- if (html40EntitiesTable[i].value >= value) {
- if (html40EntitiesTable[i].value > value)
- break;
- return((htmlEntityDescPtr) &html40EntitiesTable[i]);
- }
- }
- return(NULL);
+ nmemb = sizeof(html40EntitiesTable) / sizeof(html40EntitiesTable[0]);
+ desc = bsearch(&value, html40EntitiesTable, nmemb, sizeof(htmlEntityDesc),
+ htmlCompareEntityDesc);
+
+ return(desc);
}
/**
@@ -2292,47 +2243,6 @@ htmlEncodeEntities(unsigned char* out, int *outlen,
return(0);
}
-/************************************************************************
- * *
- * Commodity functions to handle streams *
- * *
- ************************************************************************/
-
-#ifdef LIBXML_PUSH_ENABLED
-/**
- * htmlNewInputStream:
- * @ctxt: an HTML parser context
- *
- * Create a new input stream structure
- * Returns the new input stream or NULL
- */
-static htmlParserInputPtr
-htmlNewInputStream(htmlParserCtxtPtr ctxt) {
- htmlParserInputPtr input;
-
- input = (xmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
- if (input == NULL) {
- htmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
- return(NULL);
- }
- memset(input, 0, sizeof(htmlParserInput));
- input->filename = NULL;
- input->directory = NULL;
- input->base = NULL;
- input->cur = NULL;
- input->buf = NULL;
- input->line = 1;
- input->col = 1;
- input->buf = NULL;
- input->free = NULL;
- input->version = NULL;
- input->consumed = 0;
- input->length = 0;
- return(input);
-}
-#endif
-
-
/************************************************************************
* *
* Commodity functions, cleanup needed ? *
@@ -2438,10 +2348,8 @@ htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
* Allocate a new document and fill the fields.
*/
cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
- if (cur == NULL) {
- htmlErrMemory(NULL, "HTML document creation failed\n");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlDoc));
cur->type = XML_HTML_DOCUMENT_NODE;
@@ -2461,8 +2369,15 @@ htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
cur->charset = XML_CHAR_ENCODING_UTF8;
cur->properties = XML_DOC_HTML | XML_DOC_USERBUILT;
if ((ExternalID != NULL) ||
- (URI != NULL))
- xmlCreateIntSubset(cur, BAD_CAST "html", ExternalID, URI);
+ (URI != NULL)) {
+ xmlDtdPtr intSubset;
+
+ intSubset = xmlCreateIntSubset(cur, BAD_CAST "html", ExternalID, URI);
+ if (intSubset == NULL) {
+ xmlFree(cur);
+ return(NULL);
+ }
+ }
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
@@ -2510,12 +2425,14 @@ htmlSkipBogusComment(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_HTML_INCORRECTLY_OPENED_COMMENT,
"Incorrectly opened comment\n", NULL, NULL);
- do {
+ while (PARSER_STOPPED(ctxt) == 0) {
c = CUR;
if (c == 0)
break;
NEXT;
- } while (c != '>');
+ if (c == '>')
+ break;
+ }
}
/**
@@ -2550,7 +2467,7 @@ htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
ret = xmlDictLookup(ctxt->dict, loc, i);
if (ret == NULL)
- htmlErrMemory(ctxt, NULL);
+ htmlErrMemory(ctxt);
return(ret);
}
@@ -2571,6 +2488,7 @@ static const xmlChar *
htmlParseHTMLName_nonInvasive(htmlParserCtxtPtr ctxt) {
int i = 0;
xmlChar loc[HTML_PARSER_BUFFER_SIZE];
+ const xmlChar *ret;
if (!IS_ASCII_LETTER(NXT(1)) && (NXT(1) != '_') &&
(NXT(1) != ':')) return(NULL);
@@ -2583,7 +2501,11 @@ htmlParseHTMLName_nonInvasive(htmlParserCtxtPtr ctxt) {
i++;
}
- return(xmlDictLookup(ctxt->dict, loc, i));
+ ret = xmlDictLookup(ctxt->dict, loc, i);
+ if (ret == NULL)
+ htmlErrMemory(ctxt);
+
+ return(ret);
}
@@ -2625,6 +2547,8 @@ htmlParseName(htmlParserCtxtPtr ctxt) {
if ((*in > 0) && (*in < 0x80)) {
count = in - ctxt->input->cur;
ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
+ if (ret == NULL)
+ htmlErrMemory(ctxt);
ctxt->input->cur = in;
ctxt->input->col += count;
return(ret);
@@ -2641,6 +2565,7 @@ htmlParseNameComplex(xmlParserCtxtPtr ctxt) {
XML_MAX_TEXT_LENGTH :
XML_MAX_NAME_LENGTH;
const xmlChar *base = ctxt->input->base;
+ const xmlChar *ret;
/*
* Handler for more complex cases
@@ -2673,8 +2598,6 @@ htmlParseNameComplex(xmlParserCtxtPtr ctxt) {
return(htmlParseNameComplex(ctxt));
}
}
- if (ctxt->instate == XML_PARSER_EOF)
- return(NULL);
if (ctxt->input->cur - ctxt->input->base < len) {
/* Sanity check */
@@ -2683,7 +2606,11 @@ htmlParseNameComplex(xmlParserCtxtPtr ctxt) {
return (NULL);
}
- return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+ ret = xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len);
+ if (ret == NULL)
+ htmlErrMemory(ctxt);
+
+ return(ret);
}
@@ -2716,7 +2643,7 @@ htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
buffer_size = HTML_PARSER_BUFFER_SIZE;
buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
if (buffer == NULL) {
- htmlErrMemory(ctxt, "buffer allocation failed\n");
+ htmlErrMemory(ctxt);
return(NULL);
}
out = buffer;
@@ -2724,7 +2651,8 @@ htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
/*
* Ok loop until we reach one of the ending chars
*/
- while ((CUR != 0) && (CUR != stop)) {
+ while ((PARSER_STOPPED(ctxt) == 0) &&
+ (CUR != 0) && (CUR != stop)) {
if ((stop == 0) && (CUR == '>')) break;
if ((stop == 0) && (IS_BLANK_CH(CUR))) break;
if (CUR == '&') {
@@ -2810,10 +2738,6 @@ htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
out = &buffer[indx];
}
c = CUR_CHAR(l);
- if (ctxt->instate == XML_PARSER_EOF) {
- xmlFree(buffer);
- return(NULL);
- }
if (c < 0x80)
{ *out++ = c; bits= -6; }
else if (c < 0x800)
@@ -2966,7 +2890,8 @@ htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
return(ret);
startPosition = CUR_PTR - BASE_PTR;
- while ((CUR != 0) && (CUR != quote)) {
+ while ((PARSER_STOPPED(ctxt) == 0) &&
+ (CUR != 0) && (CUR != quote)) {
/* TODO: Handle UTF-8 */
if (!IS_CHAR_CH(CUR)) {
htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
@@ -2980,8 +2905,13 @@ htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
"Unfinished SystemLiteral\n", NULL, NULL);
} else {
- if (err == 0)
+ if (err == 0) {
ret = xmlStrndup((BASE_PTR+startPosition), len);
+ if (ret == NULL) {
+ htmlErrMemory(ctxt);
+ return(NULL);
+ }
+ }
NEXT;
}
@@ -3021,7 +2951,8 @@ htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
return(ret);
startPosition = CUR_PTR - BASE_PTR;
- while ((CUR != 0) && (CUR != quote)) {
+ while ((PARSER_STOPPED(ctxt) == 0) &&
+ (CUR != 0) && (CUR != quote)) {
if (!IS_PUBIDCHAR_CH(CUR)) {
htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
"Invalid char in PubidLiteral 0x%X\n", CUR);
@@ -3035,8 +2966,13 @@ htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
"Unfinished PubidLiteral\n", NULL, NULL);
} else {
- if (err == 0)
+ if (err == 0) {
ret = xmlStrndup((BASE_PTR + startPosition), len);
+ if (ret == NULL) {
+ htmlErrMemory(ctxt);
+ return(NULL);
+ }
+ }
NEXT;
}
@@ -3125,9 +3061,6 @@ htmlParseScript(htmlParserCtxtPtr ctxt) {
cur = CUR_CHAR(l);
}
- if (ctxt->instate == XML_PARSER_EOF)
- return;
-
if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
buf[nbchar] = 0;
if (ctxt->sax->cdataBlock!= NULL) {
@@ -3163,9 +3096,10 @@ htmlParseCharDataInternal(htmlParserCtxtPtr ctxt, int readahead) {
buf[nbchar++] = readahead;
cur = CUR_CHAR(l);
- while (((cur != '<') || (ctxt->token == '<')) &&
- ((cur != '&') || (ctxt->token == '&')) &&
- (cur != 0)) {
+ while ((cur != '<') &&
+ (cur != '&') &&
+ (cur != 0) &&
+ (!PARSER_STOPPED(ctxt))) {
if (!(IS_CHAR(cur))) {
htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
"Invalid char in CDATA 0x%X\n", cur);
@@ -3200,8 +3134,6 @@ htmlParseCharDataInternal(htmlParserCtxtPtr ctxt, int readahead) {
}
cur = CUR_CHAR(l);
}
- if (ctxt->instate == XML_PARSER_EOF)
- return;
if (nbchar != 0) {
buf[nbchar] = 0;
@@ -3301,12 +3233,11 @@ htmlParseExternalID(htmlParserCtxtPtr ctxt, xmlChar **publicID) {
}
/**
- * xmlParsePI:
- * @ctxt: an XML parser context
- *
- * parse an XML Processing Instruction.
+ * htmlParsePI:
+ * @ctxt: an HTML parser context
*
- * [16] PI ::= '' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
+ * Parse an XML Processing Instruction. HTML5 doesn't allow processing
+ * instructions, so this will be removed at some point.
*/
static void
htmlParsePI(htmlParserCtxtPtr ctxt) {
@@ -3344,13 +3275,11 @@ htmlParsePI(htmlParserCtxtPtr ctxt) {
(ctxt->sax->processingInstruction != NULL))
ctxt->sax->processingInstruction(ctxt->userData,
target, NULL);
- ctxt->instate = state;
- return;
+ goto done;
}
buf = (xmlChar *) xmlMallocAtomic(size);
if (buf == NULL) {
- htmlErrMemory(ctxt, NULL);
- ctxt->instate = state;
+ htmlErrMemory(ctxt);
return;
}
cur = CUR;
@@ -3367,9 +3296,8 @@ htmlParsePI(htmlParserCtxtPtr ctxt) {
size *= 2;
tmp = (xmlChar *) xmlRealloc(buf, size);
if (tmp == NULL) {
- htmlErrMemory(ctxt, NULL);
+ htmlErrMemory(ctxt);
xmlFree(buf);
- ctxt->instate = state;
return;
}
buf = tmp;
@@ -3385,17 +3313,12 @@ htmlParsePI(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_ERR_PI_NOT_FINISHED,
"PI %s too long", target, NULL);
xmlFree(buf);
- ctxt->instate = state;
- return;
+ goto done;
}
NEXTL(l);
cur = CUR_CHAR(l);
}
buf[len] = 0;
- if (ctxt->instate == XML_PARSER_EOF) {
- xmlFree(buf);
- return;
- }
if (cur != '>') {
htmlParseErr(ctxt, XML_ERR_PI_NOT_FINISHED,
"ParsePI: PI %s never end ...\n", target, NULL);
@@ -3415,6 +3338,8 @@ htmlParsePI(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_ERR_PI_NOT_STARTED,
"PI is not started correctly", NULL, NULL);
}
+
+done:
ctxt->instate = state;
}
}
@@ -3423,9 +3348,7 @@ htmlParsePI(htmlParserCtxtPtr ctxt) {
* htmlParseComment:
* @ctxt: an HTML parser context
*
- * Parse an XML (SGML) comment
- *
- * [15] Comment ::= ''
+ * Parse an HTML comment
*/
static void
htmlParseComment(htmlParserCtxtPtr ctxt) {
@@ -3452,8 +3375,7 @@ htmlParseComment(htmlParserCtxtPtr ctxt) {
SKIP(4);
buf = (xmlChar *) xmlMallocAtomic(size);
if (buf == NULL) {
- htmlErrMemory(ctxt, "buffer allocation failed\n");
- ctxt->instate = state;
+ htmlErrMemory(ctxt);
return;
}
len = 0;
@@ -3497,8 +3419,7 @@ htmlParseComment(htmlParserCtxtPtr ctxt) {
tmp = (xmlChar *) xmlRealloc(buf, size);
if (tmp == NULL) {
xmlFree(buf);
- htmlErrMemory(ctxt, "growing buffer failed\n");
- ctxt->instate = state;
+ htmlErrMemory(ctxt);
return;
}
buf = tmp;
@@ -3526,10 +3447,6 @@ htmlParseComment(htmlParserCtxtPtr ctxt) {
}
finished:
buf[len] = 0;
- if (ctxt->instate == XML_PARSER_EOF) {
- xmlFree(buf);
- return;
- }
if (cur == '>') {
NEXT;
if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
@@ -3563,12 +3480,8 @@ int
htmlParseCharRef(htmlParserCtxtPtr ctxt) {
int val = 0;
- if ((ctxt == NULL) || (ctxt->input == NULL)) {
- htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
- "htmlParseCharRef: context error\n",
- NULL, NULL);
+ if ((ctxt == NULL) || (ctxt->input == NULL))
return(0);
- }
if ((CUR == '&') && (NXT(1) == '#') &&
((NXT(2) == 'x') || NXT(2) == 'X')) {
SKIP(3);
@@ -3681,7 +3594,7 @@ htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
"DOCTYPE improperly terminated\n", NULL, NULL);
/* Ignore bogus content */
while ((CUR != 0) && (CUR != '>') &&
- (ctxt->instate != XML_PARSER_EOF))
+ (PARSER_STOPPED(ctxt) == 0))
NEXT;
}
if (CUR == '>')
@@ -3762,6 +3675,7 @@ htmlParseAttribute(htmlParserCtxtPtr ctxt, xmlChar **value) {
static void
htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
const xmlChar *encoding;
+ xmlChar *copy;
if (!attvalue)
return;
@@ -3777,7 +3691,10 @@ htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
encoding = xmlStrcasestr(attvalue, BAD_CAST"=");
if (encoding && *encoding == '=') {
encoding ++;
- xmlSetDeclaredEncoding(ctxt, xmlStrdup(encoding));
+ copy = xmlStrdup(encoding);
+ if (copy == NULL)
+ htmlErrMemory(ctxt);
+ xmlSetDeclaredEncoding(ctxt, copy);
}
}
@@ -3802,13 +3719,21 @@ htmlCheckMeta(htmlParserCtxtPtr ctxt, const xmlChar **atts) {
att = atts[i++];
while (att != NULL) {
value = atts[i++];
- if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"http-equiv"))
- && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
- http = 1;
- else if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"charset")))
- xmlSetDeclaredEncoding(ctxt, xmlStrdup(value));
- else if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"content")))
- content = value;
+ if (value != NULL) {
+ if ((!xmlStrcasecmp(att, BAD_CAST "http-equiv")) &&
+ (!xmlStrcasecmp(value, BAD_CAST "Content-Type"))) {
+ http = 1;
+ } else if (!xmlStrcasecmp(att, BAD_CAST "charset")) {
+ xmlChar *copy;
+
+ copy = xmlStrdup(value);
+ if (copy == NULL)
+ htmlErrMemory(ctxt);
+ xmlSetDeclaredEncoding(ctxt, copy);
+ } else if (!xmlStrcasecmp(att, BAD_CAST "content")) {
+ content = value;
+ }
+ }
att = atts[i++];
}
if ((http) && (content != NULL))
@@ -3848,13 +3773,8 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
int i;
int discardtag = 0;
- if ((ctxt == NULL) || (ctxt->input == NULL)) {
- htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
- "htmlParseStartTag: context error\n", NULL, NULL);
+ if ((ctxt == NULL) || (ctxt->input == NULL))
return -1;
- }
- if (ctxt->instate == XML_PARSER_EOF)
- return(-1);
if (CUR != '<') return -1;
NEXT;
@@ -3869,7 +3789,7 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
NULL, NULL);
/* Dump the bogus tag like browsers do */
while ((CUR != 0) && (CUR != '>') &&
- (ctxt->instate != XML_PARSER_EOF))
+ (PARSER_STOPPED(ctxt) == 0))
NEXT;
return -1;
}
@@ -3927,7 +3847,7 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
while ((CUR != 0) &&
(CUR != '>') &&
((CUR != '/') || (NXT(1) != '>')) &&
- (ctxt->instate != XML_PARSER_EOF)) {
+ (PARSER_STOPPED(ctxt) == 0)) {
GROW;
attname = htmlParseAttribute(ctxt, &attvalue);
if (attname != NULL) {
@@ -3953,7 +3873,7 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
atts = (const xmlChar **)
xmlMalloc(maxatts * sizeof(xmlChar *));
if (atts == NULL) {
- htmlErrMemory(ctxt, NULL);
+ htmlErrMemory(ctxt);
if (attvalue != NULL)
xmlFree(attvalue);
goto failed;
@@ -3967,7 +3887,7 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
n = (const xmlChar **) xmlRealloc((void *) atts,
maxatts * sizeof(const xmlChar *));
if (n == NULL) {
- htmlErrMemory(ctxt, NULL);
+ htmlErrMemory(ctxt);
if (attvalue != NULL)
xmlFree(attvalue);
goto failed;
@@ -3989,7 +3909,7 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
while ((CUR != 0) &&
!(IS_BLANK_CH(CUR)) && (CUR != '>') &&
((CUR != '/') || (NXT(1) != '>')) &&
- (ctxt->instate != XML_PARSER_EOF))
+ (PARSER_STOPPED(ctxt) == 0))
NEXT;
}
@@ -4066,7 +3986,8 @@ htmlParseEndTag(htmlParserCtxtPtr ctxt)
htmlParseErr(ctxt, XML_ERR_GT_REQUIRED,
"End tag : expected '>'\n", NULL, NULL);
/* Skip to next '>' */
- while ((CUR != 0) && (CUR != '>'))
+ while ((PARSER_STOPPED(ctxt) == 0) &&
+ (CUR != 0) && (CUR != '>'))
NEXT;
}
if (CUR == '>')
@@ -4227,12 +4148,9 @@ htmlParseContent(htmlParserCtxtPtr ctxt) {
currentNode = xmlStrdup(ctxt->name);
depth = ctxt->nameNr;
- while (1) {
+ while (!PARSER_STOPPED(ctxt)) {
GROW;
- if (ctxt->instate == XML_PARSER_EOF)
- break;
-
/*
* Our tag or one of it's parent or children is ending.
*/
@@ -4387,14 +4305,8 @@ htmlParseElement(htmlParserCtxtPtr ctxt) {
int depth;
const xmlChar *oldptr;
- if ((ctxt == NULL) || (ctxt->input == NULL)) {
- htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
- "htmlParseElement: context error\n", NULL, NULL);
+ if ((ctxt == NULL) || (ctxt->input == NULL))
return;
- }
-
- if (ctxt->instate == XML_PARSER_EOF)
- return;
/* Capture start position */
if (ctxt->record_info) {
@@ -4534,14 +4446,8 @@ htmlParseElementInternal(htmlParserCtxtPtr ctxt) {
htmlParserNodeInfo node_info = { NULL, 0, 0, 0, 0 };
int failed;
- if ((ctxt == NULL) || (ctxt->input == NULL)) {
- htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
- "htmlParseElementInternal: context error\n", NULL, NULL);
+ if ((ctxt == NULL) || (ctxt->input == NULL))
return;
- }
-
- if (ctxt->instate == XML_PARSER_EOF)
- return;
/* Capture start position */
if (ctxt->record_info) {
@@ -4632,16 +4538,13 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
} else {
currentNode = xmlStrdup(ctxt->name);
if (currentNode == NULL) {
- htmlErrMemory(ctxt, NULL);
+ htmlErrMemory(ctxt);
return;
}
}
- while (1) {
+ while (PARSER_STOPPED(ctxt) == 0) {
GROW;
- if (ctxt->instate == XML_PARSER_EOF)
- break;
-
/*
* Our tag or one of it's parent or children is ending.
*/
@@ -4657,7 +4560,7 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
} else {
currentNode = xmlStrdup(ctxt->name);
if (currentNode == NULL) {
- htmlErrMemory(ctxt, NULL);
+ htmlErrMemory(ctxt);
break;
}
}
@@ -4681,10 +4584,14 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
if (currentNode != NULL)
xmlFree(currentNode);
- currentNode = xmlStrdup(ctxt->name);
- if (currentNode == NULL) {
- htmlErrMemory(ctxt, NULL);
- break;
+ if (ctxt->name == NULL) {
+ currentNode = NULL;
+ } else {
+ currentNode = xmlStrdup(ctxt->name);
+ if (currentNode == NULL) {
+ htmlErrMemory(ctxt);
+ break;
+ }
}
depth = ctxt->nameNr;
continue;
@@ -4708,10 +4615,14 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
htmlParserFinishElementParsing(ctxt);
if (currentNode != NULL) xmlFree(currentNode);
- currentNode = xmlStrdup(ctxt->name);
- if (currentNode == NULL) {
- htmlErrMemory(ctxt, NULL);
- break;
+ if (ctxt->name == NULL) {
+ currentNode = NULL;
+ } else {
+ currentNode = xmlStrdup(ctxt->name);
+ if (currentNode == NULL) {
+ htmlErrMemory(ctxt);
+ break;
+ }
}
depth = ctxt->nameNr;
continue;
@@ -4763,10 +4674,14 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
htmlParseElementInternal(ctxt);
if (currentNode != NULL) xmlFree(currentNode);
- currentNode = xmlStrdup(ctxt->name);
- if (currentNode == NULL) {
- htmlErrMemory(ctxt, NULL);
- break;
+ if (ctxt->name == NULL) {
+ currentNode = NULL;
+ } else {
+ currentNode = xmlStrdup(ctxt->name);
+ if (currentNode == NULL) {
+ htmlErrMemory(ctxt);
+ break;
+ }
}
depth = ctxt->nameNr;
}
@@ -4824,30 +4739,27 @@ __htmlParseContent(void *ctxt) {
* htmlParseDocument:
* @ctxt: an HTML parser context
*
- * parse an HTML document (and build a tree if using the standard SAX
- * interface).
+ * Parse an HTML document and invoke the SAX handlers. This is useful
+ * if you're only interested in custom SAX callbacks. If you want a
+ * document tree, use htmlCtxtParseDocument.
*
- * Returns 0, -1 in case of error. the parser context is augmented
- * as a result of the parsing.
+ * Returns 0, -1 in case of error.
*/
int
htmlParseDocument(htmlParserCtxtPtr ctxt) {
xmlDtdPtr dtd;
- xmlInitParser();
-
- if ((ctxt == NULL) || (ctxt->input == NULL)) {
- htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
- "htmlParseDocument: context error\n", NULL, NULL);
- return(XML_ERR_INTERNAL_ERROR);
- }
+ if ((ctxt == NULL) || (ctxt->input == NULL))
+ return(-1);
/*
- * SAX: beginning of the document processing.
+ * Document locator is unused. Only for backward compatibility.
*/
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) {
+ xmlSAXLocator copy = xmlDefaultSAXLocator;
+ ctxt->sax->setDocumentLocator(ctxt->userData, ©);
+ }
xmlDetectEncoding(ctxt);
@@ -4871,7 +4783,6 @@ htmlParseDocument(htmlParserCtxtPtr ctxt) {
if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
ctxt->sax->startDocument(ctxt->userData);
-
/*
* Parse possible comments and PIs before any content
*/
@@ -4900,9 +4811,10 @@ htmlParseDocument(htmlParserCtxtPtr ctxt) {
/*
* Parse possible comments and PIs before any content
*/
- while (((CUR == '<') && (NXT(1) == '!') &&
- (NXT(2) == '-') && (NXT(3) == '-')) ||
- ((CUR == '<') && (NXT(1) == '?'))) {
+ while ((PARSER_STOPPED(ctxt) == 0) &&
+ (((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == '-') && (NXT(3) == '-')) ||
+ ((CUR == '<') && (NXT(1) == '?')))) {
htmlParseComment(ctxt);
htmlParsePI(ctxt);
SKIP_BLANKS;
@@ -4928,11 +4840,14 @@ htmlParseDocument(htmlParserCtxtPtr ctxt) {
if ((!(ctxt->options & HTML_PARSE_NODEFDTD)) && (ctxt->myDoc != NULL)) {
dtd = xmlGetIntSubset(ctxt->myDoc);
- if (dtd == NULL)
+ if (dtd == NULL) {
ctxt->myDoc->intSubset =
xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
+ if (ctxt->myDoc->intSubset == NULL)
+ htmlErrMemory(ctxt);
+ }
}
if (! ctxt->wellFormed) return(-1);
return(0);
@@ -4964,17 +4879,13 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt, const htmlSAXHandler *sax,
memset(ctxt, 0, sizeof(htmlParserCtxt));
ctxt->dict = xmlDictCreate();
- if (ctxt->dict == NULL) {
- htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
+ if (ctxt->dict == NULL)
return(-1);
- }
if (ctxt->sax == NULL)
ctxt->sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler));
- if (ctxt->sax == NULL) {
- htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
+ if (ctxt->sax == NULL)
return(-1);
- }
if (sax == NULL) {
memset(ctxt->sax, 0, sizeof(htmlSAXHandler));
xmlSAX2InitHtmlDefaultSAXHandler(ctxt->sax);
@@ -4987,13 +4898,8 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt, const htmlSAXHandler *sax,
/* Allocate the Input stack */
ctxt->inputTab = (htmlParserInputPtr *)
xmlMalloc(5 * sizeof(htmlParserInputPtr));
- if (ctxt->inputTab == NULL) {
- htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
+ if (ctxt->inputTab == NULL)
return(-1);
- }
ctxt->inputNr = 0;
ctxt->inputMax = 5;
ctxt->input = NULL;
@@ -5004,35 +4910,16 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt, const htmlSAXHandler *sax,
/* Allocate the Node stack */
ctxt->nodeTab = (htmlNodePtr *) xmlMalloc(10 * sizeof(htmlNodePtr));
- if (ctxt->nodeTab == NULL) {
- htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
+ if (ctxt->nodeTab == NULL)
return(-1);
- }
ctxt->nodeNr = 0;
ctxt->nodeMax = 10;
ctxt->node = NULL;
/* Allocate the Name stack */
ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
- if (ctxt->nameTab == NULL) {
- htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
- ctxt->nameNr = 0;
- ctxt->nameMax = 0;
- ctxt->name = NULL;
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
+ if (ctxt->nameTab == NULL)
return(-1);
- }
ctxt->nameNr = 0;
ctxt->nameMax = 10;
ctxt->name = NULL;
@@ -5076,7 +4963,19 @@ htmlFreeParserCtxt(htmlParserCtxtPtr ctxt)
/**
* htmlNewParserCtxt:
*
- * Allocate and initialize a new parser context.
+ * Allocate and initialize a new HTML parser context.
+ *
+ * This can be used to parse HTML documents into DOM trees with
+ * functions like xmlCtxtReadFile or xmlCtxtReadMemory.
+ *
+ * See htmlCtxtUseOptions for parser options.
+ *
+ * See xmlCtxtSetErrorHandler for advanced error handling.
+ *
+ * See xmlNewInputURL, xmlNewInputMemory, xmlNewInputIO and similar
+ * functions for advanced input control.
+ *
+ * See htmlNewSAXParserCtxt for custom SAX parsers.
*
* Returns the htmlParserCtxtPtr or NULL in case of allocation error
*/
@@ -5092,8 +4991,14 @@ htmlNewParserCtxt(void)
* @sax: SAX handler
* @userData: user data
*
- * Allocate and initialize a new SAX parser context. If userData is NULL,
- * the parser context will be passed as user data.
+ * Allocate and initialize a new HTML SAX parser context. If userData
+ * is NULL, the parser context will be passed as user data.
+ *
+ * Available since 2.11.0. If you want support older versions,
+ * it's best to invoke htmlNewParserCtxt and set ctxt->sax with
+ * struct assignment.
+ *
+ * Also see htmlNewParserCtxt.
*
* Returns the htmlParserCtxtPtr or NULL in case of allocation error
*/
@@ -5103,11 +5008,11 @@ htmlNewSAXParserCtxt(const htmlSAXHandler *sax, void *userData)
{
xmlParserCtxtPtr ctxt;
+ xmlInitParser();
+
ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
- if (ctxt == NULL) {
- htmlErrMemory(NULL, "NewParserCtxt: out of memory\n");
+ if (ctxt == NULL)
return(NULL);
- }
memset(ctxt, 0, sizeof(xmlParserCtxt));
if (htmlInitParserCtxt(ctxt, sax, userData) < 0) {
htmlFreeParserCtxt(ctxt);
@@ -5116,67 +5021,65 @@ htmlNewSAXParserCtxt(const htmlSAXHandler *sax, void *userData)
return(ctxt);
}
-/**
- * htmlCreateMemoryParserCtxt:
- * @buffer: a pointer to a char array
- * @size: the size of the array
- *
- * Create a parser context for an HTML in-memory document.
- *
- * Returns the new parser context or NULL
- */
-htmlParserCtxtPtr
-htmlCreateMemoryParserCtxt(const char *buffer, int size) {
+static htmlParserCtxtPtr
+htmlCreateMemoryParserCtxtInternal(const char *url,
+ const char *buffer, size_t size,
+ const char *encoding) {
xmlParserCtxtPtr ctxt;
xmlParserInputPtr input;
- xmlParserInputBufferPtr buf;
if (buffer == NULL)
return(NULL);
- if (size <= 0)
- return(NULL);
ctxt = htmlNewParserCtxt();
if (ctxt == NULL)
return(NULL);
- buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
- if (buf == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- input = xmlNewInputStream(ctxt);
+ input = xmlNewInputMemory(ctxt, url, buffer, size, encoding, 0);
if (input == NULL) {
- xmlFreeParserInputBuffer(buf);
xmlFreeParserCtxt(ctxt);
- return(NULL);
+ return(NULL);
}
- input->filename = NULL;
- input->buf = buf;
- xmlBufResetInput(buf->buffer, input);
-
inputPush(ctxt, input);
+
return(ctxt);
}
/**
- * htmlCreateDocParserCtxt:
- * @str: a pointer to an array of xmlChar
- * @encoding: a free form C string describing the HTML document encoding, or NULL
+ * htmlCreateMemoryParserCtxt:
+ * @buffer: a pointer to a char array
+ * @size: the size of the array
*
- * Create a parser context for an HTML document.
+ * DEPRECATED: Use htmlNewParserCtxt and htmlCtxtReadMemory.
*
- * TODO: check the need to add encoding handling there
+ * Create a parser context for an HTML in-memory document. The input
+ * buffer must not contain any terminating null bytes.
*
* Returns the new parser context or NULL
*/
+htmlParserCtxtPtr
+htmlCreateMemoryParserCtxt(const char *buffer, int size) {
+ if (size <= 0)
+ return(NULL);
+
+ return(htmlCreateMemoryParserCtxtInternal(NULL, buffer, size, NULL));
+}
+
+/**
+ * htmlCreateDocParserCtxt:
+ * @str: a pointer to an array of xmlChar
+ * @encoding: encoding (optional)
+ *
+ * Create a parser context for a null-terminated string.
+ *
+ * Returns the new parser context or NULL if a memory allocation failed.
+ */
static htmlParserCtxtPtr
-htmlCreateDocParserCtxt(const xmlChar *str, const char *encoding) {
+htmlCreateDocParserCtxt(const xmlChar *str, const char *url,
+ const char *encoding) {
xmlParserCtxtPtr ctxt;
xmlParserInputPtr input;
- xmlParserInputBufferPtr buf;
if (str == NULL)
return(NULL);
@@ -5185,55 +5088,14 @@ htmlCreateDocParserCtxt(const xmlChar *str, const char *encoding) {
if (ctxt == NULL)
return(NULL);
- buf = xmlParserInputBufferCreateString(str);
- if (buf == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- input = xmlNewInputStream(ctxt);
+ input = xmlNewInputString(ctxt, url, (const char *) str, encoding, 0);
if (input == NULL) {
- xmlFreeParserInputBuffer(buf);
xmlFreeParserCtxt(ctxt);
return(NULL);
}
- input->filename = NULL;
- input->buf = buf;
- xmlBufResetInput(buf->buffer, input);
-
inputPush(ctxt, input);
- if (encoding != NULL) {
- xmlCharEncoding enc;
- xmlCharEncodingHandlerPtr handler;
-
- enc = xmlParseCharEncoding(encoding);
- /*
- * registered set of known encodings
- */
- if (enc != XML_CHAR_ENCODING_ERROR) {
- xmlSwitchEncoding(ctxt, enc);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
- "Unsupported encoding %s\n",
- (const xmlChar *) encoding, NULL);
- }
- } else {
- /*
- * fallback for unknown encodings
- */
- handler = xmlFindCharEncodingHandler((const char *) encoding);
- if (handler != NULL) {
- xmlSwitchToEncoding(ctxt, handler);
- } else {
- htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
- "Unsupported encoding %s\n",
- (const xmlChar *) encoding, NULL);
- }
- }
- }
-
return(ctxt);
}
@@ -5379,7 +5241,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
htmlParserNodeInfo node_info;
- while (1) {
+ while (PARSER_STOPPED(ctxt) == 0) {
in = ctxt->input;
if (in == NULL) break;
@@ -5434,14 +5296,13 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
SKIP_BLANKS;
avail = in->end - in->cur;
}
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData,
- &xmlDefaultSAXLocator);
+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) {
+ xmlSAXLocator copy = xmlDefaultSAXLocator;
+ ctxt->sax->setDocumentLocator(ctxt->userData, ©);
+ }
if ((ctxt->sax) && (ctxt->sax->startDocument) &&
(!ctxt->disableSAX))
ctxt->sax->startDocument(ctxt->userData);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
cur = in->cur[0];
next = in->cur[1];
@@ -5454,8 +5315,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
(htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
goto done;
htmlParseDocTypeDecl(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_PROLOG;
} else {
ctxt->instate = XML_PARSER_MISC;
@@ -5486,16 +5345,12 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0))
goto done;
htmlParseComment(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_MISC;
} else if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
(htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
goto done;
htmlParsePI(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_MISC;
} else if ((cur == '<') && (next == '!') &&
(UPP(2) == 'D') && (UPP(3) == 'O') &&
@@ -5506,8 +5361,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
(htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
goto done;
htmlParseDocTypeDecl(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_PROLOG;
} else if ((cur == '<') && (next == '!') &&
(avail < 9)) {
@@ -5528,16 +5381,12 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0))
goto done;
htmlParseComment(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_PROLOG;
} else if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
(htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
goto done;
htmlParsePI(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_PROLOG;
} else if ((cur == '<') && (next == '!') &&
(avail < 4)) {
@@ -5563,16 +5412,12 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0))
goto done;
htmlParseComment(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_EPILOG;
} else if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
(htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
goto done;
htmlParsePI(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_EPILOG;
} else if ((cur == '<') && (next == '!') &&
(avail < 4)) {
@@ -5655,8 +5500,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, name);
htmlnamePop(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_CONTENT;
break;
}
@@ -5679,8 +5522,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
if (ctxt->record_info)
htmlNodeInfoPush(ctxt, &node_info);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_CONTENT;
break;
}
@@ -5697,8 +5538,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
if (ctxt->record_info)
htmlNodeInfoPush(ctxt, &node_info);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_CONTENT;
break;
}
@@ -5708,14 +5547,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
/*
* Handle preparsed entities and charRef
*/
- if (ctxt->token != 0) {
- chr[0] = ctxt->token;
- htmlCheckParagraph(ctxt);
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, chr, 1);
- ctxt->token = 0;
- ctxt->checkIndex = 0;
- }
if ((avail == 1) && (terminate)) {
cur = in->cur[0];
if ((cur != '<') && (cur != '&')) {
@@ -5738,7 +5569,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
ctxt->userData, chr, 1);
}
}
- ctxt->token = 0;
ctxt->checkIndex = 0;
in->cur++;
break;
@@ -5771,8 +5601,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
}
}
htmlParseScript(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
if ((cur == '<') && (next == '/')) {
ctxt->instate = XML_PARSER_END_TAG;
ctxt->checkIndex = 0;
@@ -5800,8 +5628,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
(htmlParseLookupCommentEnd(ctxt) < 0))
goto done;
htmlParseComment(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_CONTENT;
} else {
if ((!terminate) &&
@@ -5814,8 +5640,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
(htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
goto done;
htmlParsePI(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_CONTENT;
} else if ((cur == '<') && (next == '/')) {
ctxt->instate = XML_PARSER_END_TAG;
@@ -5844,7 +5668,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
(htmlParseLookupSequence(ctxt, '<', 0, 0, 0) < 0))
goto done;
ctxt->checkIndex = 0;
- while ((ctxt->instate != XML_PARSER_EOF) &&
+ while ((PARSER_STOPPED(ctxt) == 0) &&
(cur != '<') && (in->cur < in->end)) {
if (cur == '&') {
htmlParseReference(ctxt);
@@ -5864,8 +5688,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
(htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
goto done;
htmlParseEndTag(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
if (ctxt->nameNr == 0) {
ctxt->instate = XML_PARSER_EPILOG;
} else {
@@ -5897,11 +5719,14 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
(ctxt->instate == XML_PARSER_EPILOG))) {
xmlDtdPtr dtd;
dtd = xmlGetIntSubset(ctxt->myDoc);
- if (dtd == NULL)
+ if (dtd == NULL) {
ctxt->myDoc->intSubset =
xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
+ if (ctxt->myDoc->intSubset == NULL)
+ htmlErrMemory(ctxt);
+ }
}
return(ret);
}
@@ -5909,24 +5734,33 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
/**
* htmlParseChunk:
* @ctxt: an HTML parser context
- * @chunk: an char array
- * @size: the size in byte of the chunk
+ * @chunk: chunk of memory
+ * @size: size of chunk in bytes
* @terminate: last chunk indicator
*
- * Parse a Chunk of memory
+ * Parse a chunk of memory in push parser mode.
+ *
+ * Assumes that the parser context was initialized with
+ * htmlCreatePushParserCtxt.
*
- * Returns zero if no error, the xmlParserErrors otherwise.
+ * The last chunk, which will often be empty, must be marked with
+ * the @terminate flag. With the default SAX callbacks, the resulting
+ * document will be available in ctxt->myDoc. This pointer will not
+ * be freed by the library.
+ *
+ * If the document isn't well-formed, ctxt->myDoc is set to NULL.
+ *
+ * Returns an xmlParserErrors code (0 on success).
*/
int
htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
int terminate) {
- if ((ctxt == NULL) || (ctxt->input == NULL)) {
- htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
- "htmlParseChunk: context error\n", NULL, NULL);
- return(XML_ERR_INTERNAL_ERROR);
- }
+ if ((ctxt == NULL) || (ctxt->input == NULL))
+ return(XML_ERR_ARGUMENT);
+ if (PARSER_STOPPED(ctxt) != 0)
+ return(ctxt->errNo);
if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
+ (ctxt->input->buf != NULL)) {
size_t pos = ctxt->input->cur - ctxt->input->base;
int res;
@@ -5941,12 +5775,6 @@ htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
}
htmlParseTryOrFinish(ctxt, terminate);
if (terminate) {
- if ((ctxt->instate != XML_PARSER_EOF) &&
- (ctxt->instate != XML_PARSER_EPILOG) &&
- (ctxt->instate != XML_PARSER_MISC)) {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- ctxt->wellFormed = 0;
- }
if (ctxt->instate != XML_PARSER_EOF) {
if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
ctxt->sax->endDocument(ctxt->userData);
@@ -5964,77 +5792,37 @@ htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
/**
* htmlCreatePushParserCtxt:
- * @sax: a SAX handler
- * @user_data: The user data returned on SAX callbacks
- * @chunk: a pointer to an array of chars
+ * @sax: a SAX handler (optional)
+ * @user_data: The user data returned on SAX callbacks (optional)
+ * @chunk: a pointer to an array of chars (optional)
* @size: number of chars in the array
- * @filename: an optional file name or URI
- * @enc: an optional encoding
+ * @filename: only used for error reporting (optional)
+ * @enc: encoding (deprecated, pass XML_CHAR_ENCODING_NONE)
*
- * Create a parser context for using the HTML parser in push mode
- * The value of @filename is used for fetching external entities
- * and error/warning reports.
+ * Create a parser context for using the HTML parser in push mode.
*
- * Returns the new parser context or NULL
+ * Returns the new parser context or NULL if a memory allocation
+ * failed.
*/
htmlParserCtxtPtr
htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
const char *chunk, int size, const char *filename,
xmlCharEncoding enc) {
htmlParserCtxtPtr ctxt;
- htmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
-
- xmlInitParser();
-
- buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
- if (buf == NULL) return(NULL);
+ htmlParserInputPtr input;
+ const char *encoding;
ctxt = htmlNewSAXParserCtxt(sax, user_data);
- if (ctxt == NULL) {
- xmlFreeParserInputBuffer(buf);
+ if (ctxt == NULL)
return(NULL);
- }
- if (filename == NULL) {
- ctxt->directory = NULL;
- } else {
- ctxt->directory = xmlParserGetDirectory(filename);
- }
- inputStream = htmlNewInputStream(ctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- xmlFreeParserInputBuffer(buf);
+ encoding = xmlGetCharEncodingName(enc);
+ input = xmlNewInputPush(ctxt, filename, chunk, size, encoding);
+ if (input == NULL) {
+ htmlFreeParserCtxt(ctxt);
return(NULL);
}
-
- if (filename == NULL)
- inputStream->filename = NULL;
- else
- inputStream->filename = (char *)
- xmlCanonicPath((const xmlChar *) filename);
- inputStream->buf = buf;
- xmlBufResetInput(buf->buffer, inputStream);
-
- inputPush(ctxt, inputStream);
-
- if (enc != XML_CHAR_ENCODING_NONE)
- xmlSwitchEncoding(ctxt, enc);
-
- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL)) {
- size_t pos = ctxt->input->cur - ctxt->input->base;
- int res;
-
- res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
- xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
- if (res < 0) {
- htmlParseErr(ctxt, ctxt->input->buf->error,
- "xmlParserInputBufferPush failed\n", NULL, NULL);
- xmlHaltParser(ctxt);
- }
- }
- ctxt->progressive = 1;
+ inputPush(ctxt, input);
return(ctxt);
}
@@ -6063,25 +5851,20 @@ htmlSAXParseDoc(const xmlChar *cur, const char *encoding,
htmlDocPtr ret;
htmlParserCtxtPtr ctxt;
- xmlInitParser();
-
- if (cur == NULL) return(NULL);
+ if (cur == NULL)
+ return(NULL);
+ ctxt = htmlCreateDocParserCtxt(cur, NULL, encoding);
+ if (ctxt == NULL)
+ return(NULL);
- ctxt = htmlCreateDocParserCtxt(cur, encoding);
- if (ctxt == NULL) return(NULL);
if (sax != NULL) {
- if (ctxt->sax != NULL) xmlFree (ctxt->sax);
- ctxt->sax = sax;
+ *ctxt->sax = *sax;
ctxt->userData = userData;
}
htmlParseDocument(ctxt);
ret = ctxt->myDoc;
- if (sax != NULL) {
- ctxt->sax = NULL;
- ctxt->userData = NULL;
- }
htmlFreeParserCtxt(ctxt);
return(ret);
@@ -6090,9 +5873,13 @@ htmlSAXParseDoc(const xmlChar *cur, const char *encoding,
/**
* htmlParseDoc:
* @cur: a pointer to an array of xmlChar
- * @encoding: a free form C string describing the HTML document encoding, or NULL
+ * @encoding: the encoding (optional)
+ *
+ * DEPRECATED: Use htmlReadDoc.
+ *
+ * Parse an HTML in-memory document and build a tree.
*
- * parse an HTML in-memory document and build a tree.
+ * This function uses deprecated global parser options.
*
* Returns the resulting document tree
*/
@@ -6106,20 +5893,24 @@ htmlParseDoc(const xmlChar *cur, const char *encoding) {
/**
* htmlCreateFileParserCtxt:
* @filename: the filename
- * @encoding: a free form C string describing the HTML document encoding, or NULL
+ * @encoding: optional encoding
+ *
+ * DEPRECATED: Use htmlNewParserCtxt and htmlCtxtReadFile.
+ *
+ * Create a parser context to read from a file.
+ *
+ * A non-NULL encoding overrides encoding declarations in the document.
*
- * Create a parser context for a file content.
* Automatic support for ZLIB/Compress compressed document is provided
* by default if found at compile-time.
*
- * Returns the new parser context or NULL
+ * Returns the new parser context or NULL if a memory allocation failed.
*/
htmlParserCtxtPtr
htmlCreateFileParserCtxt(const char *filename, const char *encoding)
{
htmlParserCtxtPtr ctxt;
- htmlParserInputPtr inputStream;
- char *canonicFilename;
+ htmlParserInputPtr input;
if (filename == NULL)
return(NULL);
@@ -6128,30 +5919,13 @@ htmlCreateFileParserCtxt(const char *filename, const char *encoding)
if (ctxt == NULL) {
return(NULL);
}
- canonicFilename = (char *) xmlCanonicPath((const xmlChar *) filename);
- if (canonicFilename == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
- inputStream = xmlLoadExternalEntity(canonicFilename, NULL, ctxt);
- xmlFree(canonicFilename);
- if (inputStream == NULL) {
+ input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
+ if (input == NULL) {
xmlFreeParserCtxt(ctxt);
return(NULL);
}
-
- inputPush(ctxt, inputStream);
-
- /* set encoding */
- if (encoding) {
- xmlCharEncodingHandlerPtr hdlr;
-
- hdlr = xmlFindCharEncodingHandler(encoding);
- if (hdlr != NULL) {
- xmlSwitchToEncoding(ctxt, hdlr);
- }
- }
+ inputPush(ctxt, input);
return(ctxt);
}
@@ -6159,7 +5933,7 @@ htmlCreateFileParserCtxt(const char *filename, const char *encoding)
/**
* htmlSAXParseFile:
* @filename: the filename
- * @encoding: a free form C string describing the HTML document encoding, or NULL
+ * @encoding: encoding (optional)
* @sax: the SAX handler block
* @userData: if using SAX, this pointer will be provided on callbacks.
*
@@ -6181,8 +5955,6 @@ htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr s
htmlParserCtxtPtr ctxt;
htmlSAXHandlerPtr oldsax = NULL;
- xmlInitParser();
-
ctxt = htmlCreateFileParserCtxt(filename, encoding);
if (ctxt == NULL) return(NULL);
if (sax != NULL) {
@@ -6206,10 +5978,11 @@ htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr s
/**
* htmlParseFile:
* @filename: the filename
- * @encoding: a free form C string describing the HTML document encoding, or NULL
+ * @encoding: encoding (optional)
*
- * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
- * compressed document is provided by default if found at compile-time.
+ * Parse an HTML file and build a tree.
+ *
+ * See xmlNewInputURL for details.
*
* Returns the resulting document tree
*/
@@ -6223,6 +5996,8 @@ htmlParseFile(const char *filename, const char *encoding) {
* htmlHandleOmittedElem:
* @val: int 0 or 1
*
+ * DEPRECATED: Use HTML_PARSE_NOIMPLIED
+ *
* Set and return the previous value for handling HTML omitted tags.
*
* Returns the last value for 0 for no handling, 1 for auto insertion.
@@ -6328,7 +6103,7 @@ htmlAttrAllowed(const htmlElemDesc* elt, const xmlChar* attr, int legacy) {
* for other nodes, HTML_NA (no checks performed)
*/
htmlStatus
-htmlNodeStatus(const htmlNodePtr node, int legacy) {
+htmlNodeStatus(htmlNodePtr node, int legacy) {
if ( ! node )
return HTML_INVALID ;
@@ -6380,7 +6155,6 @@ htmlCtxtReset(htmlParserCtxtPtr ctxt)
if (ctxt == NULL)
return;
- xmlInitParser();
dict = ctxt->dict;
while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
@@ -6410,8 +6184,6 @@ htmlCtxtReset(htmlParserCtxtPtr ctxt)
ctxt->version = NULL;
DICT_FREE(ctxt->encoding);
ctxt->encoding = NULL;
- DICT_FREE(ctxt->directory);
- ctxt->directory = NULL;
DICT_FREE(ctxt->extSubURI);
ctxt->extSubURI = NULL;
DICT_FREE(ctxt->extSubSystem);
@@ -6424,9 +6196,7 @@ htmlCtxtReset(htmlParserCtxtPtr ctxt)
ctxt->hasExternalSubset = 0;
ctxt->hasPErefs = 0;
ctxt->html = 1;
- ctxt->external = 0;
ctxt->instate = XML_PARSER_START;
- ctxt->token = 0;
ctxt->wellFormed = 1;
ctxt->nsWellFormed = 1;
@@ -6533,263 +6303,281 @@ htmlCtxtUseOptions(htmlParserCtxtPtr ctxt, int options)
}
/**
- * htmlDoRead:
+ * htmlCtxtParseDocument:
* @ctxt: an HTML parser context
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
- * @options: a combination of htmlParserOption(s)
- * @reuse: keep the context for reuse
+ * @input: parser input
+ *
+ * Parse an HTML document and return the resulting document tree.
*
- * Common front-end for the htmlRead functions
+ * Available since 2.13.0.
*
* Returns the resulting document tree or NULL
*/
-static htmlDocPtr
-htmlDoRead(htmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
- int options, int reuse)
+htmlDocPtr
+htmlCtxtParseDocument(htmlParserCtxtPtr ctxt, xmlParserInputPtr input)
{
htmlDocPtr ret;
- htmlCtxtUseOptions(ctxt, options);
- ctxt->html = 1;
- if (encoding != NULL) {
- xmlCharEncodingHandlerPtr hdlr;
+ if ((ctxt == NULL) || (input == NULL))
+ return(NULL);
- hdlr = xmlFindCharEncodingHandler(encoding);
- if (hdlr != NULL) {
- xmlSwitchToEncoding(ctxt, hdlr);
- }
+ /* assert(ctxt->inputNr == 0); */
+ while (ctxt->inputNr > 0)
+ xmlFreeInputStream(inputPop(ctxt));
+
+ if (inputPush(ctxt, input) < 0) {
+ xmlFreeInputStream(input);
+ return(NULL);
}
- if ((URL != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->filename == NULL))
- ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
+
+ ctxt->html = 1;
htmlParseDocument(ctxt);
- ret = ctxt->myDoc;
- ctxt->myDoc = NULL;
- if (!reuse) {
- if ((ctxt->dictNames) &&
- (ret != NULL) &&
- (ret->dict == ctxt->dict))
- ctxt->dict = NULL;
- xmlFreeParserCtxt(ctxt);
+
+ if (ctxt->errNo != XML_ERR_NO_MEMORY) {
+ ret = ctxt->myDoc;
+ } else {
+ ret = NULL;
+ xmlFreeDoc(ctxt->myDoc);
}
- return (ret);
+ ctxt->myDoc = NULL;
+
+ /* assert(ctxt->inputNr == 1); */
+ while (ctxt->inputNr > 0)
+ xmlFreeInputStream(inputPop(ctxt));
+
+ return(ret);
}
/**
* htmlReadDoc:
- * @cur: a pointer to a zero terminated string
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
- * @options: a combination of htmlParserOption(s)
+ * @str: a pointer to a zero terminated string
+ * @url: only used for error reporting (optoinal)
+ * @encoding: the document encoding (optional)
+ * @options: a combination of htmlParserOptions
*
- * parse an XML in-memory document and build a tree.
+ * Convenience function to parse an HTML document from a zero-terminated
+ * string.
*
- * Returns the resulting document tree
+ * See htmlCtxtReadDoc for details.
+ *
+ * Returns the resulting document tree.
*/
htmlDocPtr
-htmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
+htmlReadDoc(const xmlChar *str, const char *url, const char *encoding,
+ int options)
{
htmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
+ htmlDocPtr doc;
- if (cur == NULL)
- return (NULL);
-
- xmlInitParser();
- ctxt = htmlCreateDocParserCtxt(cur, NULL);
+ ctxt = htmlNewParserCtxt();
if (ctxt == NULL)
- return (NULL);
- return (htmlDoRead(ctxt, URL, encoding, options, 0));
+ return(NULL);
+
+ htmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputString(ctxt, url, (const char *) str, encoding,
+ XML_INPUT_BUF_STATIC);
+
+ doc = htmlCtxtParseDocument(ctxt, input);
+
+ htmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* htmlReadFile:
* @filename: a file or URL
- * @encoding: the document encoding, or NULL
- * @options: a combination of htmlParserOption(s)
+ * @encoding: the document encoding (optional)
+ * @options: a combination of htmlParserOptions
*
- * parse an XML file from the filesystem or the network.
+ * Convenience function to parse an HTML file from the filesystem,
+ * the network or a global user-defined resource loader.
*
- * Returns the resulting document tree
+ * See htmlCtxtReadFile for details.
+ *
+ * Returns the resulting document tree.
*/
htmlDocPtr
htmlReadFile(const char *filename, const char *encoding, int options)
{
htmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
+ htmlDocPtr doc;
- xmlInitParser();
- ctxt = htmlCreateFileParserCtxt(filename, encoding);
+ ctxt = htmlNewParserCtxt();
if (ctxt == NULL)
- return (NULL);
- return (htmlDoRead(ctxt, NULL, NULL, options, 0));
+ return(NULL);
+
+ htmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
+
+ doc = htmlCtxtParseDocument(ctxt, input);
+
+ htmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* htmlReadMemory:
* @buffer: a pointer to a char array
* @size: the size of the array
- * @URL: the base URL to use for the document
+ * @url: only used for error reporting (optional)
* @encoding: the document encoding, or NULL
* @options: a combination of htmlParserOption(s)
*
- * parse an XML in-memory document and build a tree.
+ * Convenience function to parse an HTML document from memory.
+ * The input buffer must not contain any terminating null bytes.
+ *
+ * See htmlCtxtReadMemory for details.
*
* Returns the resulting document tree
*/
htmlDocPtr
-htmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
+htmlReadMemory(const char *buffer, int size, const char *url,
+ const char *encoding, int options)
{
htmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
+ htmlDocPtr doc;
- xmlInitParser();
- ctxt = htmlCreateMemoryParserCtxt(buffer, size);
+ if (size < 0)
+ return(NULL);
+
+ ctxt = htmlNewParserCtxt();
if (ctxt == NULL)
- return (NULL);
- return (htmlDoRead(ctxt, URL, encoding, options, 0));
+ return(NULL);
+
+ htmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputMemory(ctxt, url, buffer, size, encoding,
+ XML_INPUT_BUF_STATIC);
+
+ doc = htmlCtxtParseDocument(ctxt, input);
+
+ htmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* htmlReadFd:
* @fd: an open file descriptor
- * @URL: the base URL to use for the document
+ * @url: only used for error reporting (optional)
* @encoding: the document encoding, or NULL
- * @options: a combination of htmlParserOption(s)
+ * @options: a combination of htmlParserOptions
+ *
+ * Convenience function to parse an HTML document from a
+ * file descriptor.
*
- * parse an HTML from a file descriptor and build a tree.
* NOTE that the file descriptor will not be closed when the
- * reader is closed or reset.
+ * context is freed or reset.
+ *
+ * See htmlCtxtReadFd for details.
*
* Returns the resulting document tree
*/
htmlDocPtr
-htmlReadFd(int fd, const char *URL, const char *encoding, int options)
+htmlReadFd(int fd, const char *url, const char *encoding, int options)
{
htmlParserCtxtPtr ctxt;
- xmlParserInputBufferPtr input;
- htmlParserInputPtr stream;
-
- if (fd < 0)
- return (NULL);
+ xmlParserInputPtr input;
+ htmlDocPtr doc;
- xmlInitParser();
- input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
- if (input == NULL)
- return (NULL);
- input->closecallback = NULL;
ctxt = htmlNewParserCtxt();
- if (ctxt == NULL) {
- xmlFreeParserInputBuffer(input);
- return (NULL);
- }
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- htmlFreeParserCtxt(ctxt);
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (htmlDoRead(ctxt, URL, encoding, options, 0));
+ if (ctxt == NULL)
+ return(NULL);
+
+ htmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputFd(ctxt, url, fd, encoding, 0);
+
+ doc = htmlCtxtParseDocument(ctxt, input);
+
+ htmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* htmlReadIO:
* @ioread: an I/O read function
- * @ioclose: an I/O close function
+ * @ioclose: an I/O close function (optional)
* @ioctx: an I/O handler
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
+ * @url: only used for error reporting (optional)
+ * @encoding: the document encoding (optional)
* @options: a combination of htmlParserOption(s)
*
- * parse an HTML document from I/O functions and source and build a tree.
+ * Convenience function to parse an HTML document from I/O functions
+ * and context.
+ *
+ * See htmlCtxtReadIO for details.
*
* Returns the resulting document tree
*/
htmlDocPtr
htmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
- void *ioctx, const char *URL, const char *encoding, int options)
+ void *ioctx, const char *url, const char *encoding, int options)
{
htmlParserCtxtPtr ctxt;
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
-
- if (ioread == NULL)
- return (NULL);
- xmlInitParser();
+ xmlParserInputPtr input;
+ htmlDocPtr doc;
- input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
- XML_CHAR_ENCODING_NONE);
- if (input == NULL) {
- if (ioclose != NULL)
- ioclose(ioctx);
- return (NULL);
- }
ctxt = htmlNewParserCtxt();
- if (ctxt == NULL) {
- xmlFreeParserInputBuffer(input);
- return (NULL);
- }
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- xmlFreeParserCtxt(ctxt);
+ if (ctxt == NULL)
return (NULL);
- }
- inputPush(ctxt, stream);
- return (htmlDoRead(ctxt, URL, encoding, options, 0));
+
+ htmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputIO(ctxt, url, ioread, ioclose, ioctx, encoding, 0);
+
+ doc = htmlCtxtParseDocument(ctxt, input);
+
+ htmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* htmlCtxtReadDoc:
* @ctxt: an HTML parser context
* @str: a pointer to a zero terminated string
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
- * @options: a combination of htmlParserOption(s)
+ * @URL: only used for error reporting (optional)
+ * @encoding: the document encoding (optional)
+ * @options: a combination of htmlParserOptions
+ *
+ * Parse an HTML in-memory document and build a tree.
*
- * parse an XML in-memory document and build a tree.
- * This reuses the existing @ctxt parser context
+ * See htmlCtxtUseOptions for details.
*
* Returns the resulting document tree
*/
htmlDocPtr
htmlCtxtReadDoc(htmlParserCtxtPtr ctxt, const xmlChar *str,
- const char *URL, const char *encoding, int options)
+ const char *URL, const char *encoding, int options)
{
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
if (ctxt == NULL)
return (NULL);
- if (str == NULL)
- return (NULL);
- xmlInitParser();
htmlCtxtReset(ctxt);
+ htmlCtxtUseOptions(ctxt, options);
- input = xmlParserInputBufferCreateString(str);
- if (input == NULL) {
- return(NULL);
- }
-
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- return(NULL);
- }
+ input = xmlNewInputString(ctxt, URL, (const char *) str, encoding, 0);
- inputPush(ctxt, stream);
- return (htmlDoRead(ctxt, URL, encoding, options, 1));
+ return(htmlCtxtParseDocument(ctxt, input));
}
/**
* htmlCtxtReadFile:
* @ctxt: an HTML parser context
* @filename: a file or URL
- * @encoding: the document encoding, or NULL
- * @options: a combination of htmlParserOption(s)
+ * @encoding: the document encoding (optional)
+ * @options: a combination of htmlParserOptions
+ *
+ * Parse an HTML file from the filesystem, the network or a
+ * user-defined resource loader.
*
- * parse an XML file from the filesystem or the network.
- * This reuses the existing @ctxt parser context
+ * See xmlNewInputURL and htmlCtxtUseOptions for details.
*
* Returns the resulting document tree
*/
@@ -6797,22 +6585,17 @@ htmlDocPtr
htmlCtxtReadFile(htmlParserCtxtPtr ctxt, const char *filename,
const char *encoding, int options)
{
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
- if (filename == NULL)
- return (NULL);
if (ctxt == NULL)
return (NULL);
- xmlInitParser();
htmlCtxtReset(ctxt);
+ htmlCtxtUseOptions(ctxt, options);
- stream = xmlLoadExternalEntity(filename, NULL, ctxt);
- if (stream == NULL) {
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (htmlDoRead(ctxt, NULL, encoding, options, 1));
+ input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
+
+ return(htmlCtxtParseDocument(ctxt, input));
}
/**
@@ -6820,12 +6603,14 @@ htmlCtxtReadFile(htmlParserCtxtPtr ctxt, const char *filename,
* @ctxt: an HTML parser context
* @buffer: a pointer to a char array
* @size: the size of the array
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
- * @options: a combination of htmlParserOption(s)
+ * @URL: only used for error reporting (optional)
+ * @encoding: the document encoding (optinal)
+ * @options: a combination of htmlParserOptions
*
- * parse an XML in-memory document and build a tree.
- * This reuses the existing @ctxt parser context
+ * Parse an HTML in-memory document and build a tree. The input buffer must
+ * not contain any terminating null bytes.
+ *
+ * See htmlCtxtUseOptions for details.
*
* Returns the resulting document tree
*/
@@ -6833,43 +6618,34 @@ htmlDocPtr
htmlCtxtReadMemory(htmlParserCtxtPtr ctxt, const char *buffer, int size,
const char *URL, const char *encoding, int options)
{
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
- if (ctxt == NULL)
- return (NULL);
- if (buffer == NULL)
+ if ((ctxt == NULL) || (size < 0))
return (NULL);
- xmlInitParser();
htmlCtxtReset(ctxt);
+ htmlCtxtUseOptions(ctxt, options);
- input = xmlParserInputBufferCreateStatic(buffer, size,
- XML_CHAR_ENCODING_NONE);
- if (input == NULL) {
- return(NULL);
- }
+ input = xmlNewInputMemory(ctxt, URL, buffer, size, encoding,
+ XML_INPUT_BUF_STATIC);
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- return(NULL);
- }
-
- inputPush(ctxt, stream);
- return (htmlDoRead(ctxt, URL, encoding, options, 1));
+ return(htmlCtxtParseDocument(ctxt, input));
}
/**
* htmlCtxtReadFd:
* @ctxt: an HTML parser context
* @fd: an open file descriptor
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
- * @options: a combination of htmlParserOption(s)
+ * @URL: only used for error reporting (optional)
+ * @encoding: the document encoding (optinal)
+ * @options: a combination of htmlParserOptions
+ *
+ * Parse an HTML from a file descriptor and build a tree.
*
- * parse an XML from a file descriptor and build a tree.
- * This reuses the existing @ctxt parser context
+ * See htmlCtxtUseOptions for details.
+ *
+ * NOTE that the file descriptor will not be closed when the
+ * context is freed or reset.
*
* Returns the resulting document tree
*/
@@ -6877,28 +6653,17 @@ htmlDocPtr
htmlCtxtReadFd(htmlParserCtxtPtr ctxt, int fd,
const char *URL, const char *encoding, int options)
{
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
- if (fd < 0)
- return (NULL);
if (ctxt == NULL)
- return (NULL);
- xmlInitParser();
+ return(NULL);
htmlCtxtReset(ctxt);
+ htmlCtxtUseOptions(ctxt, options);
+ input = xmlNewInputFd(ctxt, URL, fd, encoding, 0);
- input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
- if (input == NULL)
- return (NULL);
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (htmlDoRead(ctxt, URL, encoding, options, 1));
+ return(htmlCtxtParseDocument(ctxt, input));
}
/**
@@ -6911,8 +6676,9 @@ htmlCtxtReadFd(htmlParserCtxtPtr ctxt, int fd,
* @encoding: the document encoding, or NULL
* @options: a combination of htmlParserOption(s)
*
- * parse an HTML document from I/O functions and source and build a tree.
- * This reuses the existing @ctxt parser context
+ * Parse an HTML document from I/O functions and source and build a tree.
+ *
+ * See xmlNewInputIO and htmlCtxtUseOptions for details.
*
* Returns the resulting document tree
*/
@@ -6922,31 +6688,17 @@ htmlCtxtReadIO(htmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
const char *URL,
const char *encoding, int options)
{
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
- if (ioread == NULL)
- return (NULL);
if (ctxt == NULL)
return (NULL);
- xmlInitParser();
htmlCtxtReset(ctxt);
+ htmlCtxtUseOptions(ctxt, options);
- input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
- XML_CHAR_ENCODING_NONE);
- if (input == NULL) {
- if (ioclose != NULL)
- ioclose(ioctx);
- return (NULL);
- }
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (htmlDoRead(ctxt, URL, encoding, options, 1));
+ input = xmlNewInputIO(ctxt, URL, ioread, ioclose, ioctx, encoding, 0);
+
+ return(htmlCtxtParseDocument(ctxt, input));
}
#endif /* LIBXML_HTML_ENABLED */
diff --git a/HTMLtree.c b/HTMLtree.c
index 8698f53..6e8baf4 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -334,17 +334,6 @@ htmlIsBooleanAttr(const xmlChar *name)
* Output error handlers *
* *
************************************************************************/
-/**
- * htmlSaveErrMemory:
- * @extra: extra information
- *
- * Handle an out of memory condition
- */
-static void
-htmlSaveErrMemory(const char *extra)
-{
- __xmlSimpleError(XML_FROM_OUTPUT, XML_ERR_NO_MEMORY, NULL, NULL, extra);
-}
/**
* htmlSaveErr:
@@ -358,6 +347,7 @@ static void
htmlSaveErr(int code, xmlNodePtr node, const char *extra)
{
const char *msg = NULL;
+ int res;
switch(code) {
case XML_SAVE_NOT_UTF8:
@@ -375,7 +365,13 @@ htmlSaveErr(int code, xmlNodePtr node, const char *extra)
default:
msg = "unexpected error number\n";
}
- __xmlSimpleError(XML_FROM_OUTPUT, code, node, msg, extra);
+
+ res = __xmlRaiseError(NULL, NULL, NULL, NULL, node,
+ XML_FROM_OUTPUT, code, XML_ERR_ERROR, NULL, 0,
+ extra, NULL, NULL, 0, 0,
+ msg, extra);
+ if (res < 0)
+ xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_OUTPUT, NULL);
}
/************************************************************************
@@ -384,6 +380,32 @@ htmlSaveErr(int code, xmlNodePtr node, const char *extra)
* *
************************************************************************/
+static xmlCharEncodingHandler *
+htmlFindOutputEncoder(const char *encoding) {
+ xmlCharEncodingHandler *handler = NULL;
+
+ if (encoding != NULL) {
+ xmlCharEncoding enc;
+
+ enc = xmlParseCharEncoding(encoding);
+ if (enc != XML_CHAR_ENCODING_UTF8) {
+ xmlOpenCharEncodingHandler(encoding, /* output */ 1, &handler);
+ if (handler == NULL)
+ htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
+ }
+ } else {
+ /*
+ * Fallback to HTML or ASCII when the encoding is unspecified
+ */
+ if (handler == NULL)
+ xmlOpenCharEncodingHandler("HTML", /* output */ 1, &handler);
+ if (handler == NULL)
+ xmlOpenCharEncodingHandler("ascii", /* output */ 1, &handler);
+ }
+
+ return(handler);
+}
+
/**
* htmlBufNodeDumpFormat:
* @buf: the xmlBufPtr output
@@ -399,20 +421,18 @@ static size_t
htmlBufNodeDumpFormat(xmlBufPtr buf, xmlDocPtr doc, xmlNodePtr cur,
int format) {
size_t use;
- int ret;
+ size_t ret;
xmlOutputBufferPtr outbuf;
if (cur == NULL) {
- return (-1);
+ return ((size_t) -1);
}
if (buf == NULL) {
- return (-1);
+ return ((size_t) -1);
}
outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
- if (outbuf == NULL) {
- htmlSaveErrMemory("allocating HTML output buffer");
- return (-1);
- }
+ if (outbuf == NULL)
+ return ((size_t) -1);
memset(outbuf, 0, sizeof(xmlOutputBuffer));
outbuf->buffer = buf;
outbuf->encoder = NULL;
@@ -423,8 +443,11 @@ htmlBufNodeDumpFormat(xmlBufPtr buf, xmlDocPtr doc, xmlNodePtr cur,
use = xmlBufUse(buf);
htmlNodeDumpFormatOutput(outbuf, doc, cur, NULL, format);
+ if (outbuf->error)
+ ret = (size_t) -1;
+ else
+ ret = xmlBufUse(buf) - use;
xmlFree(outbuf);
- ret = xmlBufUse(buf) - use;
return (ret);
}
@@ -452,6 +475,7 @@ htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
if (buffer == NULL)
return(-1);
+ xmlBufSetAllocationScheme(buffer, XML_BUFFER_ALLOC_DOUBLEIT);
ret = htmlBufNodeDumpFormat(buffer, doc, cur, 1);
xmlBufBackToBuffer(buffer);
@@ -479,35 +503,20 @@ int
htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
xmlNodePtr cur, const char *encoding, int format) {
xmlOutputBufferPtr buf;
- xmlCharEncodingHandlerPtr handler = NULL;
+ xmlCharEncodingHandlerPtr handler;
int ret;
xmlInitParser();
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != XML_CHAR_ENCODING_UTF8) {
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
- }
- } else {
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
- }
-
/*
* save the content to a temp buffer.
*/
+ handler = htmlFindOutputEncoder(encoding);
buf = xmlOutputBufferCreateFile(out, handler);
- if (buf == NULL) return(0);
+ if (buf == NULL) {
+ xmlCharEncCloseFunc(handler);
+ return(0);
+ }
htmlNodeDumpFormatOutput(buf, doc, cur, NULL, format);
@@ -549,52 +558,34 @@ htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
if ((mem == NULL) || (size == NULL))
return;
- if (cur == NULL) {
- *mem = NULL;
- *size = 0;
+ *mem = NULL;
+ *size = 0;
+ if (cur == NULL)
return;
- }
encoding = (const char *) htmlGetMetaEncoding(cur);
-
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != XML_CHAR_ENCODING_UTF8) {
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
-
- }
- } else {
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
- }
-
+ handler = htmlFindOutputEncoder(encoding);
buf = xmlAllocOutputBufferInternal(handler);
if (buf == NULL) {
- *mem = NULL;
- *size = 0;
+ xmlCharEncCloseFunc(handler);
return;
}
htmlDocContentDumpFormatOutput(buf, cur, NULL, format);
xmlOutputBufferFlush(buf);
- if (buf->conv != NULL) {
- *size = xmlBufUse(buf->conv);
- *mem = xmlStrndup(xmlBufContent(buf->conv), *size);
- } else {
- *size = xmlBufUse(buf->buffer);
- *mem = xmlStrndup(xmlBufContent(buf->buffer), *size);
+
+ if (!buf->error) {
+ if (buf->conv != NULL) {
+ *size = xmlBufUse(buf->conv);
+ *mem = xmlStrndup(xmlBufContent(buf->conv), *size);
+ } else {
+ *size = xmlBufUse(buf->buffer);
+ *mem = xmlStrndup(xmlBufContent(buf->buffer), *size);
+ }
}
- (void)xmlOutputBufferClose(buf);
+
+ xmlOutputBufferClose(buf);
}
/**
@@ -641,15 +632,15 @@ htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
xmlOutputBufferWriteString(buf, (const char *)cur->name);
if (cur->ExternalID != NULL) {
xmlOutputBufferWriteString(buf, " PUBLIC ");
- xmlBufWriteQuotedString(buf->buffer, cur->ExternalID);
+ xmlOutputBufferWriteQuotedString(buf, cur->ExternalID);
if (cur->SystemID != NULL) {
xmlOutputBufferWriteString(buf, " ");
- xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
+ xmlOutputBufferWriteQuotedString(buf, cur->SystemID);
}
} else if (cur->SystemID != NULL &&
xmlStrcmp(cur->SystemID, BAD_CAST "about:legacy-compat")) {
xmlOutputBufferWriteString(buf, " SYSTEM ");
- xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
+ xmlOutputBufferWriteQuotedString(buf, cur->SystemID);
}
xmlOutputBufferWriteString(buf, ">\n");
}
@@ -709,17 +700,17 @@ htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
escaped = xmlURIEscapeStr(tmp,
BAD_CAST "\"#$%&+,/:;<=>?@[\\]^`{|}");
if (escaped != NULL) {
- xmlBufWriteQuotedString(buf->buffer, escaped);
+ xmlOutputBufferWriteQuotedString(buf, escaped);
xmlFree(escaped);
} else {
- xmlBufWriteQuotedString(buf->buffer, value);
+ buf->error = XML_ERR_NO_MEMORY;
}
} else {
- xmlBufWriteQuotedString(buf->buffer, value);
+ xmlOutputBufferWriteQuotedString(buf, value);
}
xmlFree(value);
} else {
- xmlOutputBufferWriteString(buf, "=\"\"");
+ buf->error = XML_ERR_NO_MEMORY;
}
}
}
@@ -860,10 +851,12 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
xmlChar *buffer;
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(buf, (const char *)buffer);
- xmlFree(buffer);
+ if (buffer == NULL) {
+ buf->error = XML_ERR_NO_MEMORY;
+ return;
}
+ xmlOutputBufferWriteString(buf, (const char *)buffer);
+ xmlFree(buffer);
} else {
xmlOutputBufferWriteString(buf, (const char *)cur->content);
}
@@ -1039,28 +1032,12 @@ htmlDocDump(FILE *f, xmlDocPtr cur) {
}
encoding = (const char *) htmlGetMetaEncoding(cur);
-
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != XML_CHAR_ENCODING_UTF8) {
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
- }
- } else {
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
- }
-
+ handler = htmlFindOutputEncoder(encoding);
buf = xmlOutputBufferCreateFile(f, handler);
- if (buf == NULL) return(-1);
+ if (buf == NULL) {
+ xmlCharEncCloseFunc(handler);
+ return(-1);
+ }
htmlDocContentDumpOutput(buf, cur, NULL);
ret = xmlOutputBufferClose(buf);
@@ -1089,31 +1066,12 @@ htmlSaveFile(const char *filename, xmlDocPtr cur) {
xmlInitParser();
encoding = (const char *) htmlGetMetaEncoding(cur);
-
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != XML_CHAR_ENCODING_UTF8) {
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
- }
- } else {
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
- }
-
- /*
- * save the content to a temp buffer.
- */
+ handler = htmlFindOutputEncoder(encoding);
buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
- if (buf == NULL) return(0);
+ if (buf == NULL) {
+ xmlCharEncCloseFunc(handler);
+ return(0);
+ }
htmlDocContentDumpOutput(buf, cur, NULL);
@@ -1144,33 +1102,20 @@ htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
xmlInitParser();
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != XML_CHAR_ENCODING_UTF8) {
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
- }
- htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
- } else {
+ handler = htmlFindOutputEncoder(encoding);
+ if (handler != NULL)
+ htmlSetMetaEncoding(cur, (const xmlChar *) handler->name);
+ else
htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
- }
-
/*
* save the content to a temp buffer.
*/
buf = xmlOutputBufferCreateFilename(filename, handler, 0);
- if (buf == NULL) return(0);
+ if (buf == NULL) {
+ xmlCharEncCloseFunc(handler);
+ return(0);
+ }
htmlDocContentDumpFormatOutput(buf, cur, encoding, format);
diff --git a/NEWS b/NEWS
index 2fef3ad..a76ffbb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,231 @@
NEWS file for libxml2
+v2.13.0: Jun 12 2024
+
+### Major changes
+
+Most of the core code should now report malloc failures reliably. Some
+API functions were extended with versions that report malloc failures.
+
+New API functions for error handling were added:
+
+- xmlCtxtSetErrorHandler
+- xmlXPathSetErrorHandler
+- xmlXIncludeSetErrorHandler
+
+This makes it possible to register per-context error handlers without
+resorting to global handlers.
+
+A few error messages were improved and consolidated. Please update
+downstream test suites accordingly.
+
+A new parser option XML_PARSE_NO_XXE can be used to disable loading
+of external entities or DTDs. This is most useful in connection with
+XML_PARSE_NOENT.
+
+Support for HTTP POST was removed.
+
+Support for zlib, liblzma and HTTP is now disabled by default and has
+to be enabled by passing --with-zlib, --with-lzma or --with-html to
+configure. In legacy mode (--with-legacy) these options are enabled
+by default as before.
+
+Support for FTP and xpointer() XPath extensions will be removed in
+the next release.
+
+Several more legacy symbols were deprecated. Users of the old "SAX1"
+API functions are encouraged to upgrade to the new "SAX2" API,
+available since version 2.6.0 from 2003.
+
+Some deprecated global variables were made const:
+
+- htmlDefaultSAXHandler
+- oldXMLWDcompatibility
+- xmlDefaultSAXHandler
+- xmlDefaultSAXLocator
+- xmlParserDebugEntities
+
+### Deprecations and removals
+
+- threads: Deprecate remaining ThrDef functions
+- unicode: Deprecate most xmlUCSIs* functions
+- memory: Remove memory debugging
+- tree: Deprecate xmlRegisterNodeDefault
+- tree: Deprecate xmlSetCompressMode
+- html: Deprecate htmlHandleOmittedElem
+- valid: Deprecate internal validation functions
+- valid: Deprecate old DTD serialization API
+- nanohttp: Deprecate public API
+- Remove VMS support
+- Remove Trio
+
+### Bug fixes
+
+- parser: Fix base URI of internal parameter entities
+- tree: Handle predefined entities in xmlBufGetEntityRefContent
+- schemas: Allow unlimited length decimals, integers etc. (Tomáš Ženčák)
+- reader: Fix preservation of attributes
+- parser: Always decode entities in namespace URIs
+- relaxng: Fix tree corruption in xmlRelaxNGParseNameClass (Seiya Nakata)
+- schemas: Fix ADD_ANNOTATION
+- tree: Fix tree iteration in xmlDOMWrapRemoveNode
+- tree: Declare namespace on clone in xmlDOMWrapCloneNode
+- tree: Fix xmlAddSibling with last sibling
+- tree: Fix xmlDocSetRootElement with multiple top-level elements
+- catalog: Fetch XML catalog before dumping
+- html: Don't close fd in htmlCtxtReadFd
+
+### Improvements
+
+- parser: Fix "Truncated multi-byte sequence" error
+- Add missing _cplusplus processing clause (Sadaf Ebrahimi)
+- parser: Rework handling of undeclared entities
+- SAX2: Warn if URI resolution failed
+- parser: Don't report error on invalid URI
+- xmllint: Clean up option handling
+- xmllint: Rework parsing
+- parser: Don't create undeclared entity refs in substitution mode
+- Make some globals const
+- reader: Make xmlTextReaderReadString non-recursive
+- reader: Rework xmlTextReaderRead{Inner,Outer}Xml
+- Remove redundant size check (Niels Dossche)
+- Remove redundant NULL check on cur (Niels Dossche)
+- Remove always-false check old == cur (Niels Dossche)
+- Remove redundant NULL check on cur (Niels Dossche)
+- tree: Don't return empty localname in xmlSplitQName{2,3}
+- xinclude: Don't try to fix base of non-elements
+- tree: Don't coalesce text nodes in xmlAdd{Prev,Next}Sibling
+- SAX2: Optimize appending children
+- tree: Align xmlAddChild with other node insertion functions
+- html: Use binary search in htmlEntityValueLookup
+- io: Allocate output buffer with XML_BUFFER_ALLOC_IO
+- encoding: Don't shrink input too early in xmlCharEncOutput
+- tree: Tighten source doc check in xmlDOMWrapAdoptNode
+- tree: Check destParent->doc in xmlDOMWrapCloneNode
+- tree: Refactor text node updates
+- tree: Refactor node insertion
+- tree: Refactor element creation and parsing of attribute values
+- tree: Simplify xmlNodeGetContent, xmlBufGetNodeContent
+- buf: Don't use default buffer size for small strings
+- string: Fix xmlStrncatNew(NULL, "")
+- entities: Don't allow null name in xmlNewEntity
+- html: Fix quadratic behavior in htmlNodeDump
+- tree: Rewrite xmlSetTreeDoc
+- valid: Rework xmlAddID
+- tree: Remove unused node types
+- tree: Make namespace comparison more consistent
+- tree: Don't allow NULL name in xmlSetNsProp
+- tree: Rework xmlNodeListGetString
+- tree: Rework xmlTextMerge
+- tree: Rework xmlNodeSetName
+- tree: Simplify xmlAddChild with text parent
+- tree: Disallow setting content of entity reference nodes
+- tree: Rework xmlReconciliateNs
+- schemas: fix spurious warning about truncated snprintf output
+ (Benjamin Gilbert)
+- xmlschemastypes: Remove unreachable if statement (Maks Mishin)
+- relaxng: Remove useless if statement (Maks Mishin)
+- tree: Check for integer overflow in xmlStringGetNodeList
+- http: Improve error message for HTTPS redirects
+- catalog: Remove Windows hack
+- save: Move DTD serialization code to xmlsave.c
+- parser: Report fatal error if document entity couldn't be loaded
+- xpath: Fix return of empty node-set in xmlXPathNodeCollectAndTest
+- SAX2: Limit entity URI length to 2000 bytes
+- parser: Account for full size of non-well-formed entities
+- parser: Pop inputs if parsing DTD failed
+- parser: Fix quadratic behavior when copying entities
+- writer: Implement xmlTextWriterClose
+- parser: Avoid duplicate namespace errors
+- parser: Add XML_PARSE_NO_XXE parser option
+- parser: Make xmlParseContent more useful
+- error: Make xmlFormatError public
+- encoding: Check whether encoding handlers support input/output
+- SAX2: Enforce size limit in xmlSAX2Text with XML_PARSE_HUGE
+- parser: Lower maximum entity nesting depth
+- parser: Set depth limit to 2048 with XML_PARSE_HUGE
+- parser: Implement xmlCtxtSetOptions
+- parser: Always prefer option members over bitmask
+- parser: Don't modify SAX2 handler if XML_PARSE_SAX1 is set
+- parser: Rework parsing of attribute and entity values
+- save: Output U+FFFD replacement characters
+- parser: Simplify entity size accounting
+- parser: Avoid unwanted expansion of parameter entities
+- parser: Always copy content from entity to target
+- parser: Simplify control flow in xmlParseReference
+- parser: Remove xmlSetEntityReferenceFunc feature
+- parser: Push general entity input streams on the stack
+- parser: Move progressive flag into input struct
+- parser: Fix in-parameter-entity and in-external-dtd checks
+- xpath: Rewrite substring-before and substring-after
+- xinclude: Only set xml:base if necessary
+- xinclude: Allow empty nodesets
+- parser: Rework general entity parsing
+- io: Fix close error handling
+- io: Fix read/write error handling
+- io: More refactoring and unescaping fixes
+- io: Move some code from xmlIO.c to parserInternals.c
+- uri: Clean up special parsing modes
+- xinclude: Rework xml:base fixup
+- parser: Also set document properties when push parsing
+- include: Move non-generated parts from xmlversion.h.in
+- io: Remove support for HTTP POST
+- dict: Move local RNG state to global state
+- dict: Get random seed from system PRNG
+- io: Don't use "-" to read from stdin
+- io: Rework initialization
+- io: Consolidate error messages
+- xzlib: Fix harmless unsigned integer overflow
+- io: Always use unbuffered input
+- io: Fix detection of compressed streams
+- io: Pass error codes from xmlFileOpenReal to xmlNewInputFromFile
+- io: Rework default callbacks
+- error: Stop printing some errors by default
+- xpath: Don't free nodes of XSLT result value trees
+- valid: Fix handling of enumerations
+- parser: Allow recovery in xmlParseInNodeContext
+- encoding: Support ASCII in xmlLookupCharEncodingHandler
+- include: Remove useless 'const' from function arguments
+- Avoid EDG -Wignored-qualifiers warnings on wrong 'const *' to '* const'
+ conversions (makise-homura)
+- Avoid EDG deprecation warnings for LCC compiler (makise-homura)
+- Avoid EDG -Woverflow warnings on truncating conversions by manually
+ truncating operand (makise-homura)
+- Avoid EDG -Wtype-limits warnings on unsigned comparisons with zero by
+ conversion from unsigned int to int (makise-homura)
+- Avoid using no_sanitize attribute on EDG even if compiler shows as GCC
+ (makise-homura)
+
+### Build systems
+
+- meson: convert boolean options to feature option (Rosen Penev)
+- meson: Pass LIBXML_STATIC in dependency (Andrew Potter)
+- meson: fix compilation with local binaries (Rosen Penev)
+- meson: don't use dl dependency on old meson (Rosen Penev)
+- meson: fix usage as a subproject (Rosen Penev)
+- autotools: Fix pthread detection on FreeBSD
+- build: Remove --with-fexceptions configuration option
+- autotools: Remove --with-coverage configuration option
+- build: Disable HTTP support by default
+- Stop defining _REENTRANT
+- doc: Don't install example code
+- meson: Initial commit (Vincent Torri)
+- build: Disable support for compression libraries by default
+- Set LIBXML2_FOUND if it has been properly configured (Michele Bianchi)
+- Makefile.am: omit $(top_builddir) from DEPS and LDADDS (Mike Dalessio)
+
+### Test suite
+
+- runtest: Work around broken EUC-JP support in musl iconv
+- runtest: Check for IBM-1141 encoding handler
+- fuzz: Add xmllint fuzzer
+- fuzz: Add fuzzer for XML reader API
+- fuzz: New tree API fuzzer
+- tests: Remove testOOM
+- Don't let gentest.py cast types to 'const somethingPtr' to avoid
+ -Wignored-qualifiers (makise-homura)
+
+
v2.12.8: Jun 12 2024
### Regressions
diff --git a/README.libxml2.md b/README.libxml2.md
index e9a5c78..58c9433 100644
--- a/README.libxml2.md
+++ b/README.libxml2.md
@@ -21,8 +21,8 @@ This code is released under the MIT License, see the Copyright file.
## Build instructions
-libxml2 can be built with GNU Autotools, CMake, or several other build
-systems in platform-specific subdirectories.
+libxml2 can be built with GNU Autotools, CMake, meson or several other
+build systems in platform-specific subdirectories.
### Autotools (for POSIX systems like Linux, BSD, macOS)
@@ -49,12 +49,11 @@ The following options disable or enable code modules and relevant symbols:
--with-history history support for shell (off)
--with-readline[=DIR] use readline in DIR (for shell history)
--with-html HTML parser (on)
- --with-http HTTP support (on)
+ --with-http HTTP support (off)
--with-iconv[=DIR] iconv support (on)
--with-icu ICU support (off)
--with-iso8859x ISO-8859-X support if no iconv (on)
- --with-lzma[=DIR] use liblzma in DIR (on)
- --with-mem-debug memory debugging module (off)
+ --with-lzma[=DIR] use liblzma in DIR (off)
--with-modules dynamic modules support (on)
--with-output serialization support (on)
--with-pattern xmlPattern selection interface (on)
@@ -62,7 +61,6 @@ The following options disable or enable code modules and relevant symbols:
--with-python Python bindings (on)
--with-reader xmlReader parsing interface (on)
--with-regexps regular expressions support (on)
- --with-run-debug runtime debugging module (off)
--with-sax1 older SAX1 interface (on)
--with-schemas XML Schemas 1.0 and RELAX NG support (on)
--with-schematron Schematron support (on)
@@ -74,7 +72,7 @@ The following options disable or enable code modules and relevant symbols:
--with-xinclude XInclude 1.0 support (on)
--with-xpath XPath 1.0 support (on)
--with-xptr XPointer support (on)
- --with-zlib[=DIR] use libz in DIR (on)
+ --with-zlib[=DIR] use libz in DIR (off)
Other options:
@@ -90,7 +88,7 @@ Now you can run the test suite with:
make check
-Please report test failures to the mailing list or bug tracker.
+Please report test failures to the bug tracker.
Then you can install the library:
@@ -121,33 +119,46 @@ Common CMake options include:
You can also open the libxml source directory with its CMakeLists.txt
directly in various IDEs such as CLion, QtCreator, or Visual Studio.
+### Meson
+
+Libxml can also be built with meson. Without option, simply call
+
+meson setup builddir
+ninja -C builddir
+
+To add options, see the meson_options.txt file. For example:
+
+meson setup -Dprefix=$prefix -Dftp=true -Dhistory=true -Dicu=true -Dhttp=true builddir
+
+To install libxml:
+
+ninja -C builddir install
+
+To launch tests:
+
+meson test -C builddir
+
## Dependencies
Libxml does not require any other libraries. A platform with somewhat
recent POSIX support should be sufficient (please report any violation
to this rule you may find).
-However, if found at configuration time, libxml will detect and use
-the following libraries:
+The iconv function is required for conversion of character encodings.
+This function is part of POSIX.1-2001. If your platform doesn't provide
+iconv, you need an external libiconv library, for example
+[GNU libiconv](https://www.gnu.org/software/libiconv/). Alternatively,
+you can use [ICU](https://icu.unicode.org/).
-- [libz](https://zlib.net/), a highly portable and widely available
- compression library.
-- [liblzma](https://tukaani.org/xz/), another compression library.
-- [libiconv](https://www.gnu.org/software/libiconv/), a character encoding
- conversion library. The iconv function is part of POSIX.1-2001, so
- libiconv isn't required on modern UNIX-like systems like Linux, BSD or
- macOS.
-- [ICU](https://icu.unicode.org/), a Unicode library. Mainly useful as an
- alternative to iconv on Windows. Unnecessary on most other systems.
+If enabled, libxml uses [libz](https://zlib.net/) or
+[liblzma](https://tukaani.org/xz/) to support reading compressed files.
+Use of this feature is discouraged.
## Contributing
The current version of the code can be found in GNOME's GitLab at
at . The best way to get involved
-is by creating issues and merge requests on GitLab. Alternatively, you can
-start discussions and send patches to the mailing list. If you want to
-work with patches, please format them with git-format-patch and use plain
-text attachments.
+is by creating issues and merge requests on GitLab.
All code must conform to C89 and pass the GitLab CI tests. Add regression
tests if possible.
diff --git a/README.md b/README.md
index c277415..bf7dcdd 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
libxml2 Windows build with Visual Studio.
-This version is libxml2-2.12.8.
+This version is libxml2-2.13.0.
Note that LZMA support is only available for VS2013 or later.
diff --git a/SAX2.c b/SAX2.c
index bb72e16..267a5fb 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -31,52 +31,16 @@
#include "private/parser.h"
#include "private/tree.h"
-/**
- * TODO:
- *
- * macro to flag unimplemented blocks
- * XML_CATALOG_PREFER user env to select between system/public preferred
- * option. C.f. Richard Tobin
- *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
- *> values "system" and "public". I have made the default be "system" to
- *> match yours.
- */
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
+#define XML_MAX_URI_LENGTH 2000
/*
* xmlSAX2ErrMemory:
* @ctxt: an XML validation parser context
* @msg: a string to accompany the error message
*/
-static void LIBXML_ATTR_FORMAT(2,0)
-xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
- xmlStructuredErrorFunc schannel = NULL;
- const char *str1 = "out of memory\n";
-
- if (ctxt != NULL) {
- ctxt->errNo = XML_ERR_NO_MEMORY;
- if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
- schannel = ctxt->sax->serror;
- __xmlRaiseError(schannel,
- ctxt->vctxt.error, ctxt->vctxt.userData,
- ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
- XML_ERR_ERROR, NULL, 0, (const char *) str1,
- NULL, NULL, 0, 0,
- msg, (const char *) str1, NULL);
- ctxt->errNo = XML_ERR_NO_MEMORY;
- ctxt->instate = XML_PARSER_EOF;
- ctxt->disableSAX = 1;
- } else {
- __xmlRaiseError(schannel,
- NULL, NULL,
- ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
- XML_ERR_ERROR, NULL, 0, (const char *) str1,
- NULL, NULL, 0, 0,
- msg, (const char *) str1, NULL);
- }
+static void
+xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt) {
+ xmlCtxtErrMemory(ctxt);
}
/**
@@ -91,32 +55,12 @@ xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
*/
static void LIBXML_ATTR_FORMAT(3,0)
xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
- const char *msg, const char *str1, const char *str2)
+ const char *msg, const xmlChar *str1, const xmlChar *str2)
{
- xmlStructuredErrorFunc schannel = NULL;
-
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL) {
- ctxt->errNo = error;
- if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
- schannel = ctxt->sax->serror;
- __xmlRaiseError(schannel,
- ctxt->vctxt.error, ctxt->vctxt.userData,
- ctxt, NULL, XML_FROM_DTD, error,
- XML_ERR_ERROR, NULL, 0, (const char *) str1,
- (const char *) str2, NULL, 0, 0,
- msg, (const char *) str1, (const char *) str2);
+ xmlCtxtErr(ctxt, NULL, XML_FROM_DTD, error, XML_ERR_ERROR,
+ str1, str2, NULL, 0, msg, str1, str2);
+ if (ctxt != NULL)
ctxt->valid = 0;
- } else {
- __xmlRaiseError(schannel,
- NULL, NULL,
- ctxt, NULL, XML_FROM_DTD, error,
- XML_ERR_ERROR, NULL, 0, (const char *) str1,
- (const char *) str2, NULL, 0, 0,
- msg, (const char *) str1, (const char *) str2);
- }
}
/**
@@ -133,21 +77,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar *str1, const xmlChar *str2)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
- XML_ERR_FATAL, NULL, 0,
- (const char *) str1, (const char *) str2,
- NULL, 0, 0, msg, str1, str2);
- if (ctxt != NULL) {
- ctxt->wellFormed = 0;
- ctxt->valid = 0;
- if (ctxt->recovery == 0)
- ctxt->disableSAX = 1;
- }
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
+ str1, str2, NULL, 0, msg, str1, str2);
}
/**
@@ -164,15 +95,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar *str1)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
- XML_ERR_WARNING, NULL, 0,
- (const char *) str1, NULL,
- NULL, 0, 0, msg, str1);
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_WARNING,
+ str1, NULL, NULL, 0, msg, str1);
}
/**
@@ -188,15 +112,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar *str1, const xmlChar *str2)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
- XML_ERR_WARNING, NULL, 0,
- (const char *) str1, (const char *) str2,
- NULL, 0, 0, msg, str1, str2);
+ xmlCtxtErr(ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_WARNING,
+ str1, str2, NULL, 0, msg, str1, str2);
}
/**
@@ -341,7 +258,7 @@ xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
ctxt->myDoc->intSubset =
xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
if (ctxt->myDoc->intSubset == NULL)
- xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");
+ xmlSAX2ErrMemory(ctxt);
}
/**
@@ -359,8 +276,9 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
if (ctx == NULL) return;
- if (((ExternalID != NULL) || (SystemID != NULL)) &&
- (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
+ if ((SystemID != NULL) &&
+ ((ctxt->options & XML_PARSE_NO_XXE) == 0) &&
+ (((ctxt->validate) || (ctxt->loadsubset)) &&
(ctxt->wellFormed && ctxt->myDoc))) {
/*
* Try to fetch and parse the external subset.
@@ -371,7 +289,6 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
xmlParserInputPtr *oldinputTab;
xmlParserInputPtr input = NULL;
const xmlChar *oldencoding;
- int oldprogressive;
unsigned long consumed;
size_t buffered;
@@ -385,7 +302,11 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
return;
}
- xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
+ if (xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID) == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ xmlFreeInputStream(input);
+ return;
+ }
/*
* make sure we won't destroy the main document context
@@ -395,21 +316,18 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
oldinputMax = ctxt->inputMax;
oldinputTab = ctxt->inputTab;
oldencoding = ctxt->encoding;
- oldprogressive = ctxt->progressive;
ctxt->encoding = NULL;
- ctxt->progressive = 0;
ctxt->inputTab = (xmlParserInputPtr *)
xmlMalloc(5 * sizeof(xmlParserInputPtr));
if (ctxt->inputTab == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset");
+ xmlSAX2ErrMemory(ctxt);
xmlFreeInputStream(input);
ctxt->input = oldinput;
ctxt->inputNr = oldinputNr;
ctxt->inputMax = oldinputMax;
ctxt->inputTab = oldinputTab;
ctxt->encoding = oldencoding;
- ctxt->progressive = oldprogressive;
return;
}
ctxt->inputNr = 0;
@@ -463,7 +381,6 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
(!xmlDictOwns(ctxt->dict, ctxt->encoding))))
xmlFree((xmlChar *) ctxt->encoding);
ctxt->encoding = oldencoding;
- ctxt->progressive = oldprogressive;
/* ctxt->wellFormed = oldwellFormed; */
}
}
@@ -486,22 +403,37 @@ xmlParserInputPtr
xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserInputPtr ret;
+ xmlParserInputPtr ret = NULL;
xmlChar *URI;
- const char *base = NULL;
+ const xmlChar *base = NULL;
+ int res;
if (ctx == NULL) return(NULL);
if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
+ base = BAD_CAST ctxt->input->filename;
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
+ if ((xmlStrlen(systemId) > XML_MAX_URI_LENGTH) ||
+ (xmlStrlen(base) > XML_MAX_URI_LENGTH)) {
+ xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT, "URI too long");
+ return(NULL);
+ }
+ res = xmlBuildURISafe(systemId, base, &URI);
+ if (URI == NULL) {
+ if (res < 0)
+ xmlSAX2ErrMemory(ctxt);
+ else
+ xmlWarnMsg(ctxt, XML_ERR_INVALID_URI,
+ "Can't resolve URI: %s\n", systemId);
+ return(NULL);
+ }
+ if (xmlStrlen(URI) > XML_MAX_URI_LENGTH) {
+ xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT, "URI too long");
+ } else {
+ ret = xmlLoadExternalEntity((const char *) URI,
+ (const char *) publicId, ctxt);
+ }
- ret = xmlLoadExternalEntity((const char *) URI,
- (const char *) publicId, ctxt);
- if (URI != NULL)
- xmlFree(URI);
+ xmlFree(URI);
return(ret);
}
@@ -590,50 +522,73 @@ xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
{
xmlEntityPtr ent;
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ int extSubset;
+ int res;
- if (ctx == NULL) return;
- if (ctxt->inSubset == 1) {
- ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
- systemId, content);
- if ((ent == NULL) && (ctxt->pedantic))
- xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED,
- "Entity(%s) already defined in the internal subset\n",
- name);
- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
- xmlChar *URI;
- const char *base = NULL;
-
- if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
-
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
- ent->URI = URI;
- }
- } else if (ctxt->inSubset == 2) {
- ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
- systemId, content);
- if ((ent == NULL) && (ctxt->pedantic) &&
- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Entity(%s) already defined in the external subset\n", name);
- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
- xmlChar *URI;
- const char *base = NULL;
-
- if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
-
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
- ent->URI = URI;
- }
- } else {
- xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
- "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
- name, NULL);
+ if ((ctxt == NULL) || (ctxt->myDoc == NULL))
+ return;
+
+ extSubset = ctxt->inSubset == 2;
+ res = xmlAddEntity(ctxt->myDoc, extSubset, name, type, publicId, systemId,
+ content, &ent);
+ switch (res) {
+ case XML_ERR_OK:
+ break;
+ case XML_ERR_NO_MEMORY:
+ xmlSAX2ErrMemory(ctxt);
+ return;
+ case XML_WAR_ENTITY_REDEFINED:
+ if (ctxt->pedantic) {
+ if (extSubset)
+ xmlWarnMsg(ctxt, res, "Entity(%s) already defined in the"
+ " external subset\n", name);
+ else
+ xmlWarnMsg(ctxt, res, "Entity(%s) already defined in the"
+ " internal subset\n", name);
+ }
+ return;
+ case XML_ERR_REDECL_PREDEF_ENTITY:
+ /*
+ * Technically an error but it's a common mistake to get double
+ * escaping according to "4.6 Predefined Entities" wrong.
+ */
+ xmlWarnMsg(ctxt, res, "Invalid redeclaration of predefined"
+ " entity '%s'", name);
+ return;
+ default:
+ xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
+ "Unexpected error code from xmlAddEntity\n",
+ NULL, NULL);
+ return;
+ }
+
+ if ((ent->URI == NULL) && (systemId != NULL)) {
+ xmlChar *URI;
+ const char *base = NULL;
+ int i;
+
+ for (i = ctxt->inputNr - 1; i >= 0; i--) {
+ if (ctxt->inputTab[i]->filename != NULL) {
+ base = ctxt->inputTab[i]->filename;
+ break;
+ }
+ }
+
+ res = xmlBuildURISafe(systemId, (const xmlChar *) base, &URI);
+
+ if (URI == NULL) {
+ if (res < 0) {
+ xmlSAX2ErrMemory(ctxt);
+ } else {
+ xmlWarnMsg(ctxt, XML_ERR_INVALID_URI,
+ "Can't resolve URI: %s\n", systemId);
+ }
+ } else if (xmlStrlen(URI) > XML_MAX_URI_LENGTH) {
+ xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT, "URI too long");
+ xmlFree(URI);
+ } else {
+ ent->URI = URI;
+ }
}
}
@@ -676,6 +631,8 @@ xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
}
/* TODO: optimize name/prefix allocation */
name = xmlSplitQName(ctxt, fullname, &prefix);
+ if (name == NULL)
+ xmlSAX2ErrMemory(ctxt);
ctxt->vctxt.valid = 1;
if (ctxt->inSubset == 1)
attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
@@ -690,6 +647,7 @@ xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
"SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
name, NULL);
xmlFree(name);
+ xmlFree(prefix);
xmlFreeEnumeration(tree);
return;
}
@@ -814,54 +772,8 @@ xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
const xmlChar *publicId, const xmlChar *systemId,
const xmlChar *notationName)
{
- xmlEntityPtr ent;
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- if (ctx == NULL) return;
- if (ctxt->inSubset == 1) {
- ent = xmlAddDocEntity(ctxt->myDoc, name,
- XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
- publicId, systemId, notationName);
- if ((ent == NULL) && (ctxt->pedantic) &&
- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Entity(%s) already defined in the internal subset\n", name);
- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
- xmlChar *URI;
- const char *base = NULL;
-
- if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
-
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
- ent->URI = URI;
- }
- } else if (ctxt->inSubset == 2) {
- ent = xmlAddDtdEntity(ctxt->myDoc, name,
- XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
- publicId, systemId, notationName);
- if ((ent == NULL) && (ctxt->pedantic) &&
- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Entity(%s) already defined in the external subset\n", name);
- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
- xmlChar *URI;
- const char *base = NULL;
-
- if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
-
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
- ent->URI = URI;
- }
- } else {
- xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
- "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
- name, NULL);
- }
+ xmlSAX2EntityDecl(ctx, name, XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
+ publicId, systemId, (xmlChar *) notationName);
}
/**
@@ -891,25 +803,19 @@ xmlSAX2StartDocument(void *ctx)
if (ctx == NULL) return;
- if (ctxt->html) {
#ifdef LIBXML_HTML_ENABLED
+ if (ctxt->html) {
if (ctxt->myDoc == NULL)
ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
if (ctxt->myDoc == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
+ xmlSAX2ErrMemory(ctxt);
return;
}
ctxt->myDoc->properties = XML_DOC_HTML;
ctxt->myDoc->parseFlags = ctxt->options;
-#else
- xmlGenericError(xmlGenericErrorContext,
- "libxml2 built without HTML support\n");
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- ctxt->instate = XML_PARSER_EOF;
- ctxt->disableSAX = 1;
- return;
+ } else
#endif
- } else {
+ {
doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
if (doc != NULL) {
doc->properties = 0;
@@ -918,7 +824,7 @@ xmlSAX2StartDocument(void *ctx)
doc->parseFlags = ctxt->options;
doc->standalone = ctxt->standalone;
} else {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
+ xmlSAX2ErrMemory(ctxt);
return;
}
if ((ctxt->dictNames) && (doc != NULL)) {
@@ -930,7 +836,7 @@ xmlSAX2StartDocument(void *ctx)
(ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename);
if (ctxt->myDoc->URL == NULL)
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
+ xmlSAX2ErrMemory(ctxt);
}
}
@@ -960,11 +866,47 @@ xmlSAX2EndDocument(void *ctx)
if (encoding != NULL) {
doc->encoding = xmlStrdup(encoding);
if (doc->encoding == NULL)
- xmlSAX2ErrMemory(ctxt, "xmlSAX2EndDocument");
+ xmlSAX2ErrMemory(ctxt);
}
}
}
+static void
+xmlSAX2AppendChild(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
+ xmlNodePtr parent;
+ xmlNodePtr last;
+
+ if (ctxt->inSubset == 1) {
+ parent = (xmlNodePtr) ctxt->myDoc->intSubset;
+ } else if (ctxt->inSubset == 2) {
+ parent = (xmlNodePtr) ctxt->myDoc->extSubset;
+ } else {
+ parent = ctxt->node;
+ if (parent == NULL)
+ parent = (xmlNodePtr) ctxt->myDoc;
+ }
+
+ last = parent->last;
+ if (last == NULL) {
+ parent->children = node;
+ } else {
+ last->next = node;
+ node->prev = last;
+ }
+
+ parent->last = node;
+ node->parent = parent;
+
+ if ((node->type != XML_TEXT_NODE) &&
+ (ctxt->linenumbers) &&
+ (ctxt->input != NULL)) {
+ if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
+ node->line = ctxt->input->line;
+ else
+ node->line = USHRT_MAX;
+ }
+}
+
#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
/**
* xmlNsErrMsg:
@@ -980,15 +922,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar *str1, const xmlChar *str2)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
- XML_ERR_ERROR, NULL, 0,
- (const char *) str1, (const char *) str2,
- NULL, 0, 0, msg, str1, str2);
+ xmlCtxtErr(ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_ERROR,
+ str1, str2, NULL, 0, msg, str1, str2);
}
/**
@@ -1041,7 +976,7 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
}
}
if (name == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+ xmlSAX2ErrMemory(ctxt);
if (ns != NULL)
xmlFree(ns);
return;
@@ -1051,6 +986,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
if ((ctxt->html) &&
(value == NULL) && (htmlIsBooleanAttr(fullname))) {
nval = xmlStrdup(fullname);
+ if (nval == NULL)
+ xmlSAX2ErrMemory(ctxt);
value = (const xmlChar *) nval;
} else
#endif
@@ -1088,12 +1025,10 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
(void) nsret;
if (!ctxt->replaceEntities) {
- ctxt->depth++;
- val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
- 0,0,0);
- ctxt->depth--;
+ /* TODO: normalize if needed */
+ val = xmlExpandEntitiesInAttValue(ctxt, value, /* normalize */ 0);
if (val == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+ xmlSAX2ErrMemory(ctxt);
if (name != NULL)
xmlFree(name);
if (nval != NULL)
@@ -1107,16 +1042,16 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
if (val[0] != 0) {
xmlURIPtr uri;
- uri = xmlParseURI((const char *)val);
+ if (xmlParseURISafe((const char *)val, &uri) < 0)
+ xmlSAX2ErrMemory(ctxt);
if (uri == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "xmlns: %s not a valid URI\n", val);
+ xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
+ "xmlns:%s: %s not a valid URI\n", name, value);
} else {
if (uri->scheme == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "xmlns: URI %s is not absolute\n", val);
+ xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
+ "xmlns:%s: URI %s is not absolute\n",
+ name, value);
}
xmlFreeURI(uri);
}
@@ -1124,16 +1059,19 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
/* a default namespace definition */
nsret = xmlNewNs(ctxt->node, val, NULL);
-
+ if (nsret == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ }
#ifdef LIBXML_VALID_ENABLED
/*
* Validate also for namespace decls, they are attributes from
* an XML-1.0 perspective
*/
- if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
- ctxt->myDoc && ctxt->myDoc->intSubset)
+ else if (ctxt->validate && ctxt->wellFormed &&
+ ctxt->myDoc && ctxt->myDoc->intSubset) {
ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
ctxt->node, prefix, nsret, val);
+ }
#endif /* LIBXML_VALID_ENABLED */
if (name != NULL)
xmlFree(name);
@@ -1153,12 +1091,10 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
(void) nsret;
if (!ctxt->replaceEntities) {
- ctxt->depth++;
- val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
- 0,0,0);
- ctxt->depth--;
+ /* TODO: normalize if needed */
+ val = xmlExpandEntitiesInAttValue(ctxt, value, /* normalize */ 0);
if (val == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+ xmlSAX2ErrMemory(ctxt);
xmlFree(ns);
if (name != NULL)
xmlFree(name);
@@ -1177,7 +1113,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
if ((ctxt->pedantic != 0) && (val[0] != 0)) {
xmlURIPtr uri;
- uri = xmlParseURI((const char *)val);
+ if (xmlParseURISafe((const char *)val, &uri) < 0)
+ xmlSAX2ErrMemory(ctxt);
if (uri == NULL) {
xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
"xmlns:%s: %s not a valid URI\n", name, value);
@@ -1193,15 +1130,20 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
/* a standard namespace definition */
nsret = xmlNewNs(ctxt->node, val, name);
xmlFree(ns);
+
+ if (nsret == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ }
#ifdef LIBXML_VALID_ENABLED
/*
* Validate also for namespace decls, they are attributes from
* an XML-1.0 perspective
*/
- if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
- ctxt->myDoc && ctxt->myDoc->intSubset)
+ else if (ctxt->validate && ctxt->wellFormed &&
+ ctxt->myDoc && ctxt->myDoc->intSubset) {
ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
ctxt->node, prefix, nsret, value);
+ }
#endif /* LIBXML_VALID_ENABLED */
if (name != NULL)
xmlFree(name);
@@ -1213,7 +1155,11 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
}
if (ns != NULL) {
- namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
+ int res;
+
+ res = xmlSearchNsSafe(ctxt->node, ns, &namespace);
+ if (res < 0)
+ xmlSAX2ErrMemory(ctxt);
if (namespace == NULL) {
xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
@@ -1228,11 +1174,11 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
if ((xmlStrEqual(name, prop->name)) &&
((namespace == prop->ns) ||
(xmlStrEqual(namespace->href, prop->ns->href)))) {
- xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
- "Attribute %s in %s redefined\n",
- name, namespace->href);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER,
+ XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL,
+ name, NULL, NULL, 0,
+ "Attribute %s in %s redefined\n",
+ name, namespace->href);
if (name != NULL)
xmlFree(name);
goto error;
@@ -1247,25 +1193,22 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
/* !!!!!! */
ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
- if (ret == NULL)
+ if (ret == NULL) {
+ xmlSAX2ErrMemory(ctxt);
goto error;
+ }
if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
- xmlNodePtr tmp;
-
- ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
- tmp = ret->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) ret;
- if (tmp->next == NULL)
- ret->last = tmp;
- tmp = tmp->next;
- }
+ if (xmlNodeParseContent((xmlNodePtr) ret, value, INT_MAX) < 0)
+ xmlSAX2ErrMemory(ctxt);
} else if (value != NULL) {
ret->children = xmlNewDocText(ctxt->myDoc, value);
- ret->last = ret->children;
- if (ret->children != NULL)
+ if (ret->children == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ } else {
+ ret->last = ret->children;
ret->children->parent = (xmlNodePtr) ret;
+ }
}
#ifdef LIBXML_VALID_ENABLED
@@ -1279,10 +1222,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
if (!ctxt->replaceEntities) {
xmlChar *val;
- ctxt->depth++;
- val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
- 0,0,0);
- ctxt->depth--;
+ /* TODO: normalize if needed */
+ val = xmlExpandEntitiesInAttValue(ctxt, value, /* normalize */ 0);
if (val == NULL)
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
@@ -1295,8 +1236,9 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
* It need to be done twice ... it's an extra burden related
* to the ability to keep xmlSAX2References in attributes
*/
- nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
- ctxt->node, fullname, val);
+ nvalnorm = xmlValidCtxtNormalizeAttributeValue(
+ &ctxt->vctxt, ctxt->myDoc,
+ ctxt->node, fullname, val);
if (nvalnorm != NULL) {
xmlFree(val);
val = nvalnorm;
@@ -1313,8 +1255,6 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
} else
#endif /* LIBXML_VALID_ENABLED */
if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
- (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
- ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) &&
/* Don't create IDs containing entity references */
(ret->children != NULL) &&
(ret->children->type == XML_TEXT_NODE) &&
@@ -1332,14 +1272,20 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
*/
if (xmlValidateNCName(content, 1) != 0) {
xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
- "xml:id : attribute value %s is not an NCName\n",
- (const char *) content, NULL);
+ "xml:id : attribute value %s is not an NCName\n",
+ content, NULL);
}
xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
- } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
- xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
- else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
- xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
+ } else {
+ int res = xmlIsID(ctxt->myDoc, ctxt->node, ret);
+
+ if (res < 0)
+ xmlCtxtErrMemory(ctxt);
+ else if (res > 0)
+ xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
+ else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
+ xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
+ }
}
error:
@@ -1391,13 +1337,15 @@ xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
if (attr->prefix != NULL) {
fulln = xmlStrdup(attr->prefix);
- fulln = xmlStrcat(fulln, BAD_CAST ":");
- fulln = xmlStrcat(fulln, attr->name);
+ if (fulln != NULL)
+ fulln = xmlStrcat(fulln, BAD_CAST ":");
+ if (fulln != NULL)
+ fulln = xmlStrcat(fulln, attr->name);
} else {
fulln = xmlStrdup(attr->name);
}
if (fulln == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+ xmlSAX2ErrMemory(ctxt);
break;
}
@@ -1419,8 +1367,8 @@ xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
if (att == NULL) {
xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED,
"standalone: attribute %s on %s defaulted from external subset\n",
- (const char *)fulln,
- (const char *)attr->elem);
+ fulln,
+ attr->elem);
}
xmlFree(fulln);
}
@@ -1463,7 +1411,7 @@ xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
if (fulln == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+ xmlSAX2ErrMemory(ctxt);
return;
}
@@ -1547,6 +1495,10 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
* Split the full name into a namespace prefix and the tag name
*/
name = xmlSplitQName(ctxt, fullname, &prefix);
+ if (name == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ return;
+ }
}
/*
@@ -1556,26 +1508,22 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
*/
ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
if (ret == NULL) {
- if (prefix != NULL)
- xmlFree(prefix);
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+ xmlFree(prefix);
+ xmlSAX2ErrMemory(ctxt);
return;
}
ctxt->nodemem = -1;
- if (ctxt->linenumbers) {
- if (ctxt->input != NULL) {
- if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
- ret->line = ctxt->input->line;
- else
- ret->line = USHRT_MAX;
- }
- }
/* Initialize parent before pushing node */
parent = ctxt->node;
if (parent == NULL)
parent = (xmlNodePtr) ctxt->myDoc;
+ /*
+ * Link the child element
+ */
+ xmlSAX2AppendChild(ctxt, ret);
+
/*
* We are parsing a new node.
*/
@@ -1587,12 +1535,9 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
return;
}
- /*
- * Link the child element
- */
- xmlAddChild(parent, ret);
-
if (!ctxt->html) {
+ int res;
+
/*
* Insert all the defaulted attributes from the DTD especially
* namespaces
@@ -1623,14 +1568,21 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
* Search the namespace, note that since the attributes have been
* processed, the local namespaces are available.
*/
- ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
- if ((ns == NULL) && (parent != NULL))
- ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
+ res = xmlSearchNsSafe(ret, prefix, &ns);
+ if (res < 0)
+ xmlSAX2ErrMemory(ctxt);
+ if ((ns == NULL) && (parent != NULL)) {
+ res = xmlSearchNsSafe(parent, prefix, &ns);
+ if (res < 0)
+ xmlSAX2ErrMemory(ctxt);
+ }
if ((prefix != NULL) && (ns == NULL)) {
- ns = xmlNewNs(ret, NULL, prefix);
xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
"Namespace prefix %s is not defined\n",
prefix, NULL);
+ ns = xmlNewNs(ret, NULL, prefix);
+ if (ns == NULL)
+ xmlSAX2ErrMemory(ctxt);
}
/*
@@ -1751,7 +1703,7 @@ xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
}
if (ret == NULL) {
- xmlErrMemory(ctxt, "xmlSAX2Characters");
+ xmlCtxtErrMemory(ctxt);
return(NULL);
}
memset(ret, 0, sizeof(xmlNode));
@@ -1772,6 +1724,11 @@ xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
} else if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
((cur == '<') && (str[len + 1] != '!')))) {
intern = xmlDictLookup(ctxt->dict, str, len);
+ if (intern == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ xmlFree(ret);
+ return(NULL);
+ }
} else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
(str[len + 1] != '!')) {
int i;
@@ -1780,6 +1737,11 @@ xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
if (!IS_BLANK_CH(str[i])) goto skip;
}
intern = xmlDictLookup(ctxt->dict, str, len);
+ if (intern == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ xmlFree(ret);
+ return(NULL);
+ }
}
}
skip:
@@ -1789,7 +1751,7 @@ xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
if (intern == NULL) {
ret->content = xmlStrndup(str, len);
if (ret->content == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode");
+ xmlSAX2ErrMemory(ctxt);
xmlFree(ret);
return(NULL);
}
@@ -1816,7 +1778,6 @@ static xmlChar *
xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
const xmlChar *end) {
const xmlChar *in;
- xmlChar *ret;
in = str;
while (in < end)
@@ -1824,11 +1785,12 @@ xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
goto decode;
return(NULL);
decode:
- ctxt->depth++;
- ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
- XML_SUBSTITUTE_REF, 0,0,0);
- ctxt->depth--;
- return(ret);
+ /*
+ * If the value contains '&', we can be sure it was allocated and is
+ * zero-terminated.
+ */
+ /* TODO: normalize if needed */
+ return(xmlExpandEntitiesInAttValue(ctxt, str, /* normalize */ 0));
}
#endif /* LIBXML_VALID_ENABLED */
@@ -1865,7 +1827,11 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
if (prefix != NULL) {
namespace = xmlParserNsLookupSax(ctxt, prefix);
if ((namespace == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
- namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
+ int res;
+
+ res = xmlSearchNsSafe(ctxt->node, prefix, &namespace);
+ if (res < 0)
+ xmlSAX2ErrMemory(ctxt);
}
}
@@ -1879,7 +1845,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
} else {
ret = xmlMalloc(sizeof(*ret));
if (ret == NULL) {
- xmlSAX2ErrMemory(ctxt, NULL);
+ xmlSAX2ErrMemory(ctxt);
return(NULL);
}
}
@@ -1900,10 +1866,13 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
ret->doc = ctxt->node->doc;
ret->ns = namespace;
- if (ctxt->dictNames)
+ if (ctxt->dictNames) {
ret->name = localname;
- else
+ } else {
ret->name = xmlStrdup(localname);
+ if (ret->name == NULL)
+ xmlSAX2ErrMemory(ctxt);
+ }
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
@@ -1924,17 +1893,10 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
tmp->doc = ret->doc;
tmp->parent = (xmlNodePtr) ret;
}
- } else {
- ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
- valueend - value);
- tmp = ret->children;
- while (tmp != NULL) {
- tmp->doc = ret->doc;
- tmp->parent = (xmlNodePtr) ret;
- if (tmp->next == NULL)
- ret->last = tmp;
- tmp = tmp->next;
- }
+ } else if (valueend > value) {
+ if (xmlNodeParseContent((xmlNodePtr) ret, value,
+ valueend - value) < 0)
+ xmlSAX2ErrMemory(ctxt);
}
} else if (value != NULL) {
xmlNodePtr tmp;
@@ -1968,6 +1930,8 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
* entry points in the full validation code
*/
dup = xmlStrndup(value, valueend - value);
+ if (dup == NULL)
+ xmlSAX2ErrMemory(ctxt);
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
ctxt->myDoc, ctxt->node, ret, dup);
@@ -1986,7 +1950,9 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
xmlChar *fullname;
fullname = xmlBuildQName(localname, prefix, fn, 50);
- if (fullname != NULL) {
+ if (fullname == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ } else {
ctxt->vctxt.valid = 1;
nvalnorm = xmlValidCtxtNormalizeAttributeValue(
&ctxt->vctxt, ctxt->myDoc,
@@ -2012,6 +1978,8 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
* the attribute as passed is already normalized
*/
dup = xmlStrndup(value, valueend - value);
+ if (dup == NULL)
+ xmlSAX2ErrMemory(ctxt);
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
ctxt->myDoc, ctxt->node, ret, dup);
@@ -2019,8 +1987,6 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
} else
#endif /* LIBXML_VALID_ENABLED */
if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
- (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
- ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) &&
/* Don't create IDs containing entity references */
(ret->children != NULL) &&
(ret->children->type == XML_TEXT_NODE) &&
@@ -2040,14 +2006,19 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
*/
if (xmlValidateNCName(content, 1) != 0) {
xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
- "xml:id : attribute value %s is not an NCName\n",
- (const char *) content, NULL);
+ "xml:id : attribute value %s is not an NCName\n",
+ content, NULL);
}
xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
- } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
- xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
- } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
- xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
+ } else {
+ int res = xmlIsID(ctxt->myDoc, ctxt->node, ret);
+
+ if (res < 0)
+ xmlCtxtErrMemory(ctxt);
+ else if (res > 0)
+ xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
+ else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
+ xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
}
}
if (dup != NULL)
@@ -2086,7 +2057,6 @@ xmlSAX2StartElementNs(void *ctx,
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlNodePtr ret;
- xmlNodePtr parent;
xmlNsPtr last = NULL, ns;
const xmlChar *uri, *pref;
xmlChar *lname = NULL;
@@ -2115,10 +2085,17 @@ xmlSAX2StartElementNs(void *ctx,
const xmlChar *fullname;
fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
- if (fullname != NULL)
- localname = fullname;
+ if (fullname == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ return;
+ }
+ localname = fullname;
} else {
lname = xmlBuildQName(localname, prefix, NULL, 0);
+ if (lname == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ return;
+ }
}
}
/*
@@ -2140,7 +2117,7 @@ xmlSAX2StartElementNs(void *ctx,
else
ret->name = lname;
if (ret->name == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
+ xmlSAX2ErrMemory(ctxt);
xmlFree(ret);
return;
}
@@ -2157,18 +2134,10 @@ xmlSAX2StartElementNs(void *ctx,
ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
(xmlChar *) lname, NULL);
if (ret == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
+ xmlSAX2ErrMemory(ctxt);
return;
}
}
- if (ctxt->linenumbers) {
- if (ctxt->input != NULL) {
- if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
- ret->line = ctxt->input->line;
- else
- ret->line = USHRT_MAX;
- }
- }
/*
* Build the namespace list
@@ -2187,11 +2156,7 @@ xmlSAX2StartElementNs(void *ctx,
if ((URI != NULL) && (prefix == pref))
ret->ns = ns;
} else {
- /*
- * any out of memory error would already have been raised
- * but we can't be guaranteed it's the actual error due to the
- * API, best is to skip in this case
- */
+ xmlSAX2ErrMemory(ctxt);
continue;
}
@@ -2207,10 +2172,10 @@ xmlSAX2StartElementNs(void *ctx,
}
ctxt->nodemem = -1;
- /* Initialize parent before pushing node */
- parent = ctxt->node;
- if (parent == NULL)
- parent = (xmlNodePtr) ctxt->myDoc;
+ /*
+ * Link the child element
+ */
+ xmlSAX2AppendChild(ctxt, ret);
/*
* We are parsing a new node.
@@ -2221,11 +2186,6 @@ xmlSAX2StartElementNs(void *ctx,
return;
}
- /*
- * Link the child element
- */
- xmlAddChild(parent, ret);
-
/*
* Insert the defaulted attributes from the DTD only if requested:
*/
@@ -2240,13 +2200,17 @@ xmlSAX2StartElementNs(void *ctx,
if ((URI != NULL) && (ret->ns == NULL)) {
ret->ns = xmlParserNsLookupSax(ctxt, prefix);
if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
- ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
+ int res;
+
+ res = xmlSearchNsSafe(ret, prefix, &ret->ns);
+ if (res < 0)
+ xmlSAX2ErrMemory(ctxt);
}
if (ret->ns == NULL) {
ns = xmlNewNs(ret, NULL, prefix);
if (ns == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
+ xmlSAX2ErrMemory(ctxt);
return;
}
if (prefix != NULL)
@@ -2278,22 +2242,26 @@ xmlSAX2StartElementNs(void *ctx,
fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
attributes[j]);
- if (fullname != NULL) {
- attr = xmlSAX2AttributeNs(ctxt, fullname, NULL,
- attributes[j+3],
- attributes[j+4]);
- goto have_attr;
- }
+ if (fullname == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ return;
+ }
+ attr = xmlSAX2AttributeNs(ctxt, fullname, NULL,
+ attributes[j+3],
+ attributes[j+4]);
+ goto have_attr;
} else {
lname = xmlBuildQName(attributes[j], attributes[j+1],
NULL, 0);
- if (lname != NULL) {
- attr = xmlSAX2AttributeNs(ctxt, lname, NULL,
- attributes[j+3],
- attributes[j+4]);
- xmlFree(lname);
- goto have_attr;
- }
+ if (lname == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ return;
+ }
+ attr = xmlSAX2AttributeNs(ctxt, lname, NULL,
+ attributes[j+3],
+ attributes[j+4]);
+ xmlFree(lname);
+ goto have_attr;
}
}
attr = xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
@@ -2383,9 +2351,12 @@ xmlSAX2Reference(void *ctx, const xmlChar *name)
if (ctx == NULL) return;
ret = xmlNewReference(ctxt->myDoc, name);
- if (xmlAddChild(ctxt->node, ret) == NULL) {
- xmlFreeNode(ret);
+ if (ret == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ return;
}
+
+ xmlSAX2AppendChild(ctxt, ret);
}
/**
@@ -2432,7 +2403,7 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
ctxt->nodelen = len;
ctxt->nodemem = len + 1;
} else {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
+ xmlSAX2ErrMemory(ctxt);
return;
}
} else {
@@ -2441,6 +2412,10 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
((type != XML_TEXT_NODE) ||
(lastChild->name == xmlStringText));
if ((coalesceText) && (ctxt->nodemem != 0)) {
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
+ XML_MAX_HUGE_LENGTH :
+ XML_MAX_TEXT_LENGTH;
+
/*
* The whole point of maintaining nodelen and nodemem,
* xmlTextConcat is too costly, i.e. compute length,
@@ -2456,16 +2431,13 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
lastChild->content = xmlStrdup(lastChild->content);
}
if (lastChild->content == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
+ xmlSAX2ErrMemory(ctxt);
return;
}
- if (ctxt->nodelen > INT_MAX - len) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
- return;
- }
- if ((ctxt->nodelen + len > XML_MAX_TEXT_LENGTH) &&
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
+ if ((len > maxLength) || (ctxt->nodelen > maxLength - len)) {
+ xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT,
+ "Text node too long, try XML_PARSE_HUGE");
+ xmlHaltParser(ctxt);
return;
}
if (ctxt->nodelen + len >= ctxt->nodemem) {
@@ -2478,7 +2450,7 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
size = size > INT_MAX / 2 ? INT_MAX : size * 2;
newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
if (newbuf == NULL) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
+ xmlSAX2ErrMemory(ctxt);
return;
}
ctxt->nodemem = size;
@@ -2489,7 +2461,7 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
lastChild->content[ctxt->nodelen] = 0;
} else if (coalesceText) {
if (xmlTextConcat(lastChild, ch, len)) {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
+ xmlSAX2ErrMemory(ctxt);
}
if (ctxt->node->children != NULL) {
ctxt->nodelen = xmlStrlen(lastChild->content);
@@ -2503,8 +2475,10 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
lastChild->doc = ctxt->myDoc;
} else
lastChild = xmlNewCDataBlock(ctxt->myDoc, ch, len);
- if (lastChild != NULL) {
- xmlAddChild(ctxt->node, lastChild);
+ if (lastChild == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ } else {
+ xmlSAX2AppendChild(ctxt, lastChild);
if (ctxt->node->children != NULL) {
ctxt->nodelen = len;
ctxt->nodemem = len + 1;
@@ -2569,38 +2543,16 @@ xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlNodePtr ret;
- xmlNodePtr parent;
if (ctx == NULL) return;
- parent = ctxt->node;
ret = xmlNewDocPI(ctxt->myDoc, target, data);
- if (ret == NULL) return;
-
- if (ctxt->linenumbers) {
- if (ctxt->input != NULL) {
- if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
- ret->line = ctxt->input->line;
- else
- ret->line = USHRT_MAX;
- }
- }
- if (ctxt->inSubset == 1) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
- return;
- } else if (ctxt->inSubset == 2) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
- return;
- }
- if (parent == NULL) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
- return;
- }
- if (parent->type == XML_ELEMENT_NODE) {
- xmlAddChild(parent, ret);
- } else {
- xmlAddSibling(parent, ret);
+ if (ret == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ return;
}
+
+ xmlSAX2AppendChild(ctxt, ret);
}
/**
@@ -2615,37 +2567,16 @@ xmlSAX2Comment(void *ctx, const xmlChar *value)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlNodePtr ret;
- xmlNodePtr parent;
if (ctx == NULL) return;
- parent = ctxt->node;
+
ret = xmlNewDocComment(ctxt->myDoc, value);
- if (ret == NULL) return;
- if (ctxt->linenumbers) {
- if (ctxt->input != NULL) {
- if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
- ret->line = ctxt->input->line;
- else
- ret->line = USHRT_MAX;
- }
+ if (ret == NULL) {
+ xmlSAX2ErrMemory(ctxt);
+ return;
}
- if (ctxt->inSubset == 1) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
- return;
- } else if (ctxt->inSubset == 2) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
- return;
- }
- if (parent == NULL) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
- return;
- }
- if (parent->type == XML_ELEMENT_NODE) {
- xmlAddChild(parent, ret);
- } else {
- xmlAddSibling(parent, ret);
- }
+ xmlSAX2AppendChild(ctxt, ret);
}
/**
diff --git a/THIS_VERSION_IS_2.12.8 b/THIS_VERSION_IS_2.13.0
similarity index 100%
rename from THIS_VERSION_IS_2.12.8
rename to THIS_VERSION_IS_2.13.0
diff --git a/buf.c b/buf.c
index 266395f..f9f59b2 100644
--- a/buf.c
+++ b/buf.c
@@ -89,10 +89,9 @@ struct _xmlBuf {
* To be improved...
*/
static void
-xmlBufMemoryError(xmlBufPtr buf, const char *extra)
+xmlBufMemoryError(xmlBufPtr buf)
{
- __xmlSimpleError(XML_FROM_BUFFER, XML_ERR_NO_MEMORY, NULL, NULL, extra);
- if ((buf) && (buf->error == 0))
+ if (buf->error == 0)
buf->error = XML_ERR_NO_MEMORY;
}
@@ -104,10 +103,9 @@ xmlBufMemoryError(xmlBufPtr buf, const char *extra)
* To be improved...
*/
static void
-xmlBufOverflowError(xmlBufPtr buf, const char *extra)
+xmlBufOverflowError(xmlBufPtr buf)
{
- __xmlSimpleError(XML_FROM_BUFFER, XML_BUF_OVERFLOW, NULL, NULL, extra);
- if ((buf) && (buf->error == 0))
+ if (buf->error == 0)
buf->error = XML_BUF_OVERFLOW;
}
@@ -123,10 +121,8 @@ xmlBufCreate(void) {
xmlBufPtr ret;
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
- if (ret == NULL) {
- xmlBufMemoryError(NULL, "creating buffer");
+ if (ret == NULL)
return(NULL);
- }
ret->use = 0;
ret->error = 0;
ret->buffer = NULL;
@@ -135,7 +131,6 @@ xmlBufCreate(void) {
ret->alloc = xmlBufferAllocScheme;
ret->content = (xmlChar *) xmlMallocAtomic(ret->size);
if (ret->content == NULL) {
- xmlBufMemoryError(ret, "creating buffer");
xmlFree(ret);
return(NULL);
}
@@ -158,10 +153,8 @@ xmlBufCreateSize(size_t size) {
if (size == SIZE_MAX)
return(NULL);
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
- if (ret == NULL) {
- xmlBufMemoryError(NULL, "creating buffer");
+ if (ret == NULL)
return(NULL);
- }
ret->use = 0;
ret->error = 0;
ret->buffer = NULL;
@@ -171,7 +164,6 @@ xmlBufCreateSize(size_t size) {
if (ret->size){
ret->content = (xmlChar *) xmlMallocAtomic(ret->size);
if (ret->content == NULL) {
- xmlBufMemoryError(ret, "creating buffer");
xmlFree(ret);
return(NULL);
}
@@ -203,8 +195,16 @@ xmlBufDetach(xmlBufPtr buf) {
if (buf->error)
return(NULL);
- ret = buf->content;
+ if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
+ (buf->content != buf->contentIO)) {
+ ret = xmlStrndup(buf->content, buf->use);
+ xmlFree(buf->contentIO);
+ } else {
+ ret = buf->content;
+ }
+
buf->content = NULL;
+ buf->contentIO = NULL;
buf->size = 0;
buf->use = 0;
UPDATE_COMPAT(buf);
@@ -383,7 +383,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
if (len < buf->size - buf->use)
return(buf->size - buf->use - 1);
if (len >= SIZE_MAX - buf->use) {
- xmlBufMemoryError(buf, "growing buffer past SIZE_MAX");
+ xmlBufMemoryError(buf);
return(0);
}
@@ -400,7 +400,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
*/
if ((buf->use + len + 1 >= XML_MAX_TEXT_LENGTH) ||
(buf->size >= XML_MAX_TEXT_LENGTH)) {
- xmlBufMemoryError(buf, "buffer error: text too long\n");
+ xmlBufMemoryError(buf);
return(0);
}
if (size >= XML_MAX_TEXT_LENGTH)
@@ -411,7 +411,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
newbuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + size);
if (newbuf == NULL) {
- xmlBufMemoryError(buf, "growing buffer");
+ xmlBufMemoryError(buf);
return(0);
}
buf->contentIO = newbuf;
@@ -419,7 +419,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
} else {
newbuf = (xmlChar *) xmlRealloc(buf->content, size);
if (newbuf == NULL) {
- xmlBufMemoryError(buf, "growing buffer");
+ xmlBufMemoryError(buf);
return(0);
}
buf->content = newbuf;
@@ -641,7 +641,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
* Used to provide parsing limits
*/
if (size >= XML_MAX_TEXT_LENGTH) {
- xmlBufMemoryError(buf, "buffer error: text too long\n");
+ xmlBufMemoryError(buf);
return(0);
}
}
@@ -662,7 +662,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
}
while (size > newSize) {
if (newSize > SIZE_MAX / 2) {
- xmlBufMemoryError(buf, "growing buffer");
+ xmlBufMemoryError(buf);
return 0;
}
newSize *= 2;
@@ -678,7 +678,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
newSize = buf->size;
while (size > newSize) {
if (newSize > SIZE_MAX / 2) {
- xmlBufMemoryError(buf, "growing buffer");
+ xmlBufMemoryError(buf);
return 0;
}
newSize *= 2;
@@ -703,7 +703,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
} else {
rebuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + newSize);
if (rebuf == NULL) {
- xmlBufMemoryError(buf, "growing buffer");
+ xmlBufMemoryError(buf);
return 0;
}
buf->contentIO = rebuf;
@@ -731,7 +731,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
}
}
if (rebuf == NULL) {
- xmlBufMemoryError(buf, "growing buffer");
+ xmlBufMemoryError(buf);
return 0;
}
buf->content = rebuf;
@@ -751,8 +751,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
* Add a string range to an XML buffer. if len == -1, the length of
* str is recomputed.
*
- * Returns 0 successful, a positive error code number otherwise
- * and -1 in case of internal or API error.
+ * Returns 0 if successful, -1 in case of error.
*/
int
xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
@@ -776,7 +775,7 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
/* Note that both buf->size and buf->use can be zero here. */
if ((size_t) len >= buf->size - buf->use) {
if ((size_t) len >= SIZE_MAX - buf->use) {
- xmlBufMemoryError(buf, "growing buffer past SIZE_MAX");
+ xmlBufMemoryError(buf);
return(-1);
}
needSize = buf->use + len + 1;
@@ -785,14 +784,12 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
* Used to provide parsing limits
*/
if (needSize >= XML_MAX_TEXT_LENGTH) {
- xmlBufMemoryError(buf, "buffer error: text too long\n");
+ xmlBufMemoryError(buf);
return(-1);
}
}
- if (!xmlBufResize(buf, needSize)){
- xmlBufMemoryError(buf, "growing buffer");
- return XML_ERR_NO_MEMORY;
- }
+ if (!xmlBufResize(buf, needSize))
+ return(-1);
}
memmove(&buf->content[buf->use], str, len);
@@ -821,72 +818,6 @@ xmlBufCat(xmlBufPtr buf, const xmlChar *str) {
return xmlBufAdd(buf, str, -1);
}
-/**
- * xmlBufCCat:
- * @buf: the buffer to dump
- * @str: the C char string
- *
- * Append a zero terminated C string to an XML buffer.
- *
- * Returns 0 successful, a positive error code number otherwise
- * and -1 in case of internal or API error.
- */
-int
-xmlBufCCat(xmlBufPtr buf, const char *str) {
- return xmlBufCat(buf, (const xmlChar *) str);
-}
-
-/**
- * xmlBufWriteQuotedString:
- * @buf: the XML buffer output
- * @string: the string to add
- *
- * routine which manage and grows an output buffer. This one writes
- * a quoted or double quoted #xmlChar string, checking first if it holds
- * quote or double-quotes internally
- *
- * Returns 0 if successful, a positive error code number otherwise
- * and -1 in case of internal or API error.
- */
-int
-xmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string) {
- const xmlChar *cur, *base;
- if ((buf == NULL) || (buf->error))
- return(-1);
- CHECK_COMPAT(buf)
- if (xmlStrchr(string, '\"')) {
- if (xmlStrchr(string, '\'')) {
- xmlBufCCat(buf, "\"");
- base = cur = string;
- while(*cur != 0){
- if(*cur == '"'){
- if (base != cur)
- xmlBufAdd(buf, base, cur - base);
- xmlBufAdd(buf, BAD_CAST """, 6);
- cur++;
- base = cur;
- }
- else {
- cur++;
- }
- }
- if (base != cur)
- xmlBufAdd(buf, base, cur - base);
- xmlBufCCat(buf, "\"");
- }
- else{
- xmlBufCCat(buf, "\'");
- xmlBufCat(buf, string);
- xmlBufCCat(buf, "\'");
- }
- } else {
- xmlBufCCat(buf, "\"");
- xmlBufCat(buf, string);
- xmlBufCCat(buf, "\"");
- }
- return(0);
-}
-
/**
* xmlBufFromBuffer:
* @buffer: incoming old buffer to convert to a new one
@@ -907,7 +838,6 @@ xmlBufFromBuffer(xmlBufferPtr buffer) {
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
if (ret == NULL) {
- xmlBufMemoryError(NULL, "creating buffer");
return(NULL);
}
ret->use = buffer->use;
@@ -941,12 +871,19 @@ xmlBufBackToBuffer(xmlBufPtr buf) {
if (buf == NULL)
return(NULL);
CHECK_COMPAT(buf)
- if ((buf->error) || (buf->buffer == NULL)) {
+ ret = buf->buffer;
+
+ if ((buf->error) || (ret == NULL)) {
xmlBufFree(buf);
+ if (ret != NULL) {
+ ret->content = NULL;
+ ret->contentIO = NULL;
+ ret->use = 0;
+ ret->size = 0;
+ }
return(NULL);
}
- ret = buf->buffer;
/*
* What to do in case of error in the buffer ???
*/
@@ -956,7 +893,7 @@ xmlBufBackToBuffer(xmlBufPtr buf) {
* maximum allowed memory for an xmlBuffer on this architecture.
* Keep the buffer but provide a truncated size value.
*/
- xmlBufOverflowError(buf, "Used size too big for xmlBuffer");
+ xmlBufOverflowError(buf);
ret->use = INT_MAX;
ret->size = INT_MAX;
} else if (buf->size > INT_MAX) {
@@ -966,7 +903,7 @@ xmlBufBackToBuffer(xmlBufPtr buf) {
* limit.
* Keep the buffer but provide a truncated size value.
*/
- xmlBufOverflowError(buf, "Allocated size too big for xmlBuffer");
+ xmlBufOverflowError(buf);
ret->use = buf->use;
ret->size = INT_MAX;
} else {
@@ -980,32 +917,6 @@ xmlBufBackToBuffer(xmlBufPtr buf) {
return(ret);
}
-/**
- * xmlBufMergeBuffer:
- * @buf: an xmlBufPtr
- * @buffer: the buffer to consume into @buf
- *
- * The content of @buffer is appended to @buf and @buffer is freed
- *
- * Returns -1 in case of error, 0 otherwise, in any case @buffer is freed
- */
-int
-xmlBufMergeBuffer(xmlBufPtr buf, xmlBufferPtr buffer) {
- int ret = 0;
-
- if ((buf == NULL) || (buf->error)) {
- xmlBufferFree(buffer);
- return(-1);
- }
- CHECK_COMPAT(buf)
- if ((buffer != NULL) && (buffer->content != NULL) &&
- (buffer->use > 0)) {
- ret = xmlBufAdd(buf, buffer->content, buffer->use);
- }
- xmlBufferFree(buffer);
- return(ret);
-}
-
/**
* xmlBufResetInput:
* @buf: an xmlBufPtr
@@ -1017,16 +928,7 @@ xmlBufMergeBuffer(xmlBufPtr buf, xmlBufferPtr buffer) {
*/
int
xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input) {
- if (input == NULL)
- return(-1);
- if ((buf == NULL) || (buf->error)) {
- input->base = input->cur = input->end = BAD_CAST "";
- return(-1);
- }
- CHECK_COMPAT(buf)
- input->base = input->cur = buf->content;
- input->end = &buf->content[buf->use];
- return(0);
+ return(xmlBufUpdateInput(buf, input, 0));
}
/**
@@ -1042,16 +944,8 @@ xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input) {
*/
int
xmlBufUpdateInput(xmlBufPtr buf, xmlParserInputPtr input, size_t pos) {
- if (input == NULL)
+ if ((buf == NULL) || (input == NULL))
return(-1);
- /*
- * TODO: It might be safer to keep using the buffer content if there
- * was an error.
- */
- if ((buf == NULL) || (buf->error)) {
- input->base = input->cur = input->end = BAD_CAST "";
- return(-1);
- }
CHECK_COMPAT(buf)
input->base = buf->content;
input->cur = input->base + pos;
diff --git a/build-VS2008/libxml2-static-for-dll/libxml2-static-for-dll.vcproj b/build-VS2008/libxml2-static-for-dll/libxml2-static-for-dll.vcproj
index c2b37a6..07d1eca 100644
--- a/build-VS2008/libxml2-static-for-dll/libxml2-static-for-dll.vcproj
+++ b/build-VS2008/libxml2-static-for-dll/libxml2-static-for-dll.vcproj
@@ -473,18 +473,6 @@
RelativePath="..\..\timsort.h"
>
-
-
-
-
-
-
diff --git a/build-VS2008/libxml2-static/libxml2-static.vcproj b/build-VS2008/libxml2-static/libxml2-static.vcproj
index 5b90a50..aea15e4 100644
--- a/build-VS2008/libxml2-static/libxml2-static.vcproj
+++ b/build-VS2008/libxml2-static/libxml2-static.vcproj
@@ -473,18 +473,6 @@
RelativePath="..\..\timsort.h"
>
-
-
-
-
-
-
diff --git a/build-VS2008/libxml2/libxml2.vcproj b/build-VS2008/libxml2/libxml2.vcproj
index 3d40974..2163ad5 100644
--- a/build-VS2008/libxml2/libxml2.vcproj
+++ b/build-VS2008/libxml2/libxml2.vcproj
@@ -505,18 +505,6 @@
RelativePath="..\..\timsort.h"
>
-
-
-
-
-
-
diff --git a/build-VS2010-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2010-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index b50aaa6..f77e874 100644
--- a/build-VS2010-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2010-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -205,9 +205,6 @@
-
-
-
diff --git a/build-VS2010-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2010-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index d8f51fa..b5d429f 100644
--- a/build-VS2010-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2010-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -161,15 +161,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2010-MT/libxml2-static/libxml2-static.vcxproj b/build-VS2010-MT/libxml2-static/libxml2-static.vcxproj
index 992f6ce..098252c 100644
--- a/build-VS2010-MT/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2010-MT/libxml2-static/libxml2-static.vcxproj
@@ -205,9 +205,6 @@
-
-
-
diff --git a/build-VS2010-MT/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2010-MT/libxml2-static/libxml2-static.vcxproj.filters
index d8f51fa..b5d429f 100644
--- a/build-VS2010-MT/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2010-MT/libxml2-static/libxml2-static.vcxproj.filters
@@ -161,15 +161,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2010-MT/libxml2/libxml2.vcxproj b/build-VS2010-MT/libxml2/libxml2.vcxproj
index 8c571ef..8175895 100644
--- a/build-VS2010-MT/libxml2/libxml2.vcxproj
+++ b/build-VS2010-MT/libxml2/libxml2.vcxproj
@@ -205,9 +205,6 @@
-
-
-
diff --git a/build-VS2010-MT/libxml2/libxml2.vcxproj.filters b/build-VS2010-MT/libxml2/libxml2.vcxproj.filters
index 68c6e7f..f9d74ac 100644
--- a/build-VS2010-MT/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2010-MT/libxml2/libxml2.vcxproj.filters
@@ -161,15 +161,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2010/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2010/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index b50aaa6..f77e874 100644
--- a/build-VS2010/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2010/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -205,9 +205,6 @@
-
-
-
diff --git a/build-VS2010/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2010/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index d8f51fa..b5d429f 100644
--- a/build-VS2010/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2010/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -161,15 +161,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2010/libxml2-static/libxml2-static.vcxproj b/build-VS2010/libxml2-static/libxml2-static.vcxproj
index 992f6ce..098252c 100644
--- a/build-VS2010/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2010/libxml2-static/libxml2-static.vcxproj
@@ -205,9 +205,6 @@
-
-
-
diff --git a/build-VS2010/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2010/libxml2-static/libxml2-static.vcxproj.filters
index d8f51fa..b5d429f 100644
--- a/build-VS2010/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2010/libxml2-static/libxml2-static.vcxproj.filters
@@ -161,15 +161,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2010/libxml2/libxml2.vcxproj b/build-VS2010/libxml2/libxml2.vcxproj
index 8c571ef..8175895 100644
--- a/build-VS2010/libxml2/libxml2.vcxproj
+++ b/build-VS2010/libxml2/libxml2.vcxproj
@@ -205,9 +205,6 @@
-
-
-
diff --git a/build-VS2010/libxml2/libxml2.vcxproj.filters b/build-VS2010/libxml2/libxml2.vcxproj.filters
index 68c6e7f..f9d74ac 100644
--- a/build-VS2010/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2010/libxml2/libxml2.vcxproj.filters
@@ -161,15 +161,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2013-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2013-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index ffdb5c7..da4c4e0 100644
--- a/build-VS2013-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2013-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2013-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2013-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2013-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2013-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2013-MT/libxml2-static/libxml2-static.vcxproj b/build-VS2013-MT/libxml2-static/libxml2-static.vcxproj
index cc6ae58..9b1a937 100644
--- a/build-VS2013-MT/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2013-MT/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2013-MT/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2013-MT/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2013-MT/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2013-MT/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2013-MT/libxml2/libxml2.vcxproj b/build-VS2013-MT/libxml2/libxml2.vcxproj
index a5b231a..39608e5 100644
--- a/build-VS2013-MT/libxml2/libxml2.vcxproj
+++ b/build-VS2013-MT/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2013-MT/libxml2/libxml2.vcxproj.filters b/build-VS2013-MT/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2013-MT/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2013-MT/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2013/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2013/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index ffdb5c7..da4c4e0 100644
--- a/build-VS2013/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2013/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2013/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2013/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2013/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2013/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2013/libxml2-static/libxml2-static.vcxproj b/build-VS2013/libxml2-static/libxml2-static.vcxproj
index cc6ae58..9b1a937 100644
--- a/build-VS2013/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2013/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2013/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2013/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2013/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2013/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2013/libxml2/libxml2.vcxproj b/build-VS2013/libxml2/libxml2.vcxproj
index a5b231a..39608e5 100644
--- a/build-VS2013/libxml2/libxml2.vcxproj
+++ b/build-VS2013/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2013/libxml2/libxml2.vcxproj.filters b/build-VS2013/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2013/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2013/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2015-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2015-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index 53ad9a2..9e91546 100644
--- a/build-VS2015-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2015-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2015-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2015-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2015-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2015-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2015-MT/libxml2-static/libxml2-static.vcxproj b/build-VS2015-MT/libxml2-static/libxml2-static.vcxproj
index fa44459..0139900 100644
--- a/build-VS2015-MT/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2015-MT/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2015-MT/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2015-MT/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2015-MT/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2015-MT/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2015-MT/libxml2/libxml2.vcxproj b/build-VS2015-MT/libxml2/libxml2.vcxproj
index dd3d676..ed4930e 100644
--- a/build-VS2015-MT/libxml2/libxml2.vcxproj
+++ b/build-VS2015-MT/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2015-MT/libxml2/libxml2.vcxproj.filters b/build-VS2015-MT/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2015-MT/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2015-MT/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2015/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2015/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index 53ad9a2..9e91546 100644
--- a/build-VS2015/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2015/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2015/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2015/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2015/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2015/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2015/libxml2-static/libxml2-static.vcxproj b/build-VS2015/libxml2-static/libxml2-static.vcxproj
index fa44459..0139900 100644
--- a/build-VS2015/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2015/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2015/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2015/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2015/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2015/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2015/libxml2/libxml2.vcxproj b/build-VS2015/libxml2/libxml2.vcxproj
index dd3d676..ed4930e 100644
--- a/build-VS2015/libxml2/libxml2.vcxproj
+++ b/build-VS2015/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2015/libxml2/libxml2.vcxproj.filters b/build-VS2015/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2015/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2015/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2017-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2017-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index bb5f7d6..d12d8eb 100644
--- a/build-VS2017-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2017-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2017-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2017-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2017-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2017-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2017-MT/libxml2-static/libxml2-static.vcxproj b/build-VS2017-MT/libxml2-static/libxml2-static.vcxproj
index ff47b66..fe62d81 100644
--- a/build-VS2017-MT/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2017-MT/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2017-MT/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2017-MT/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2017-MT/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2017-MT/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2017-MT/libxml2/libxml2.vcxproj b/build-VS2017-MT/libxml2/libxml2.vcxproj
index a35bee6..be940ec 100644
--- a/build-VS2017-MT/libxml2/libxml2.vcxproj
+++ b/build-VS2017-MT/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2017-MT/libxml2/libxml2.vcxproj.filters b/build-VS2017-MT/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2017-MT/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2017-MT/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2017/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2017/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index bb5f7d6..d12d8eb 100644
--- a/build-VS2017/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2017/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2017/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2017/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2017/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2017/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2017/libxml2-static/libxml2-static.vcxproj b/build-VS2017/libxml2-static/libxml2-static.vcxproj
index ff47b66..fe62d81 100644
--- a/build-VS2017/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2017/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2017/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2017/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2017/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2017/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2017/libxml2/libxml2.vcxproj b/build-VS2017/libxml2/libxml2.vcxproj
index a35bee6..be940ec 100644
--- a/build-VS2017/libxml2/libxml2.vcxproj
+++ b/build-VS2017/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2017/libxml2/libxml2.vcxproj.filters b/build-VS2017/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2017/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2017/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2019-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2019-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index 5915a39..4e7679c 100644
--- a/build-VS2019-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2019-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2019-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2019-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2019-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2019-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2019-MT/libxml2-static/libxml2-static.vcxproj b/build-VS2019-MT/libxml2-static/libxml2-static.vcxproj
index a89b515..f2a8928 100644
--- a/build-VS2019-MT/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2019-MT/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2019-MT/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2019-MT/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2019-MT/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2019-MT/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2019-MT/libxml2/libxml2.vcxproj b/build-VS2019-MT/libxml2/libxml2.vcxproj
index 596032d..e3bc85a 100644
--- a/build-VS2019-MT/libxml2/libxml2.vcxproj
+++ b/build-VS2019-MT/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2019-MT/libxml2/libxml2.vcxproj.filters b/build-VS2019-MT/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2019-MT/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2019-MT/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2019-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2019-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index 1587caf..705036b 100644
--- a/build-VS2019-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2019-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2019-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2019-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2019-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2019-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2019-arm/libxml2-static/libxml2-static.vcxproj b/build-VS2019-arm/libxml2-static/libxml2-static.vcxproj
index ab10353..7b8b028 100644
--- a/build-VS2019-arm/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2019-arm/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2019-arm/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2019-arm/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2019-arm/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2019-arm/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2019-arm/libxml2/libxml2.vcxproj b/build-VS2019-arm/libxml2/libxml2.vcxproj
index 61b8a44..747b949 100644
--- a/build-VS2019-arm/libxml2/libxml2.vcxproj
+++ b/build-VS2019-arm/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2019-arm/libxml2/libxml2.vcxproj.filters b/build-VS2019-arm/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2019-arm/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2019-arm/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2019/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2019/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index 5915a39..4e7679c 100644
--- a/build-VS2019/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2019/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2019/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2019/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2019/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2019/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2019/libxml2-static/libxml2-static.vcxproj b/build-VS2019/libxml2-static/libxml2-static.vcxproj
index a89b515..f2a8928 100644
--- a/build-VS2019/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2019/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2019/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2019/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2019/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2019/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2019/libxml2/libxml2.vcxproj b/build-VS2019/libxml2/libxml2.vcxproj
index 596032d..e3bc85a 100644
--- a/build-VS2019/libxml2/libxml2.vcxproj
+++ b/build-VS2019/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2019/libxml2/libxml2.vcxproj.filters b/build-VS2019/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2019/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2019/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2022-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2022-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index b7d284e..3b208d5 100644
--- a/build-VS2022-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2022-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2022-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2022-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2022-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2022-MT/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2022-MT/libxml2-static/libxml2-static.vcxproj b/build-VS2022-MT/libxml2-static/libxml2-static.vcxproj
index 5b34516..0812b88 100644
--- a/build-VS2022-MT/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2022-MT/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2022-MT/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2022-MT/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2022-MT/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2022-MT/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2022-MT/libxml2/libxml2.vcxproj b/build-VS2022-MT/libxml2/libxml2.vcxproj
index c8eec4b..f8cfc39 100644
--- a/build-VS2022-MT/libxml2/libxml2.vcxproj
+++ b/build-VS2022-MT/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2022-MT/libxml2/libxml2.vcxproj.filters b/build-VS2022-MT/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2022-MT/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2022-MT/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2022-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2022-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index 7e076f0..93169da 100644
--- a/build-VS2022-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2022-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2022-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2022-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2022-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2022-arm/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2022-arm/libxml2-static/libxml2-static.vcxproj b/build-VS2022-arm/libxml2-static/libxml2-static.vcxproj
index 84c89fa..a712177 100644
--- a/build-VS2022-arm/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2022-arm/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2022-arm/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2022-arm/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2022-arm/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2022-arm/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2022-arm/libxml2/libxml2.vcxproj b/build-VS2022-arm/libxml2/libxml2.vcxproj
index 41a192b..c1b7a23 100644
--- a/build-VS2022-arm/libxml2/libxml2.vcxproj
+++ b/build-VS2022-arm/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2022-arm/libxml2/libxml2.vcxproj.filters b/build-VS2022-arm/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2022-arm/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2022-arm/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2022/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj b/build-VS2022/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
index b7d284e..3b208d5 100644
--- a/build-VS2022/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
+++ b/build-VS2022/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2022/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters b/build-VS2022/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2022/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
+++ b/build-VS2022/libxml2-static-for-dll/libxml2-static-for-dll.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2022/libxml2-static/libxml2-static.vcxproj b/build-VS2022/libxml2-static/libxml2-static.vcxproj
index 5b34516..0812b88 100644
--- a/build-VS2022/libxml2-static/libxml2-static.vcxproj
+++ b/build-VS2022/libxml2-static/libxml2-static.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2022/libxml2-static/libxml2-static.vcxproj.filters b/build-VS2022/libxml2-static/libxml2-static.vcxproj.filters
index 9d240db..8b9ab31 100644
--- a/build-VS2022/libxml2-static/libxml2-static.vcxproj.filters
+++ b/build-VS2022/libxml2-static/libxml2-static.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/build-VS2022/libxml2/libxml2.vcxproj b/build-VS2022/libxml2/libxml2.vcxproj
index c8eec4b..f8cfc39 100644
--- a/build-VS2022/libxml2/libxml2.vcxproj
+++ b/build-VS2022/libxml2/libxml2.vcxproj
@@ -210,9 +210,6 @@
-
-
-
diff --git a/build-VS2022/libxml2/libxml2.vcxproj.filters b/build-VS2022/libxml2/libxml2.vcxproj.filters
index f4eeb14..4affb58 100644
--- a/build-VS2022/libxml2/libxml2.vcxproj.filters
+++ b/build-VS2022/libxml2/libxml2.vcxproj.filters
@@ -164,15 +164,6 @@
Header Files\win32
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
diff --git a/c14n.c b/c14n.c
index 3d2e144..964ac99 100644
--- a/c14n.c
+++ b/c14n.c
@@ -23,8 +23,8 @@
#include
#include
-#include "private/buf.h"
#include "private/error.h"
+#include "private/io.h"
/************************************************************************
* *
@@ -72,7 +72,7 @@ typedef struct _xmlC14NCtx {
static xmlC14NVisibleNsStackPtr xmlC14NVisibleNsStackCreate (void);
static void xmlC14NVisibleNsStackDestroy (xmlC14NVisibleNsStackPtr cur);
-static void xmlC14NVisibleNsStackAdd (xmlC14NVisibleNsStackPtr cur,
+static int xmlC14NVisibleNsStackAdd (xmlC14NVisibleNsStackPtr cur,
xmlNsPtr ns,
xmlNodePtr node);
static void xmlC14NVisibleNsStackSave (xmlC14NVisibleNsStackPtr cur,
@@ -134,87 +134,85 @@ static xmlChar *xmlC11NNormalizeString(const xmlChar * input,
* Handle a redefinition of memory error
*/
static void
-xmlC14NErrMemory(const char *extra)
+xmlC14NErrMemory(xmlC14NCtxPtr ctxt)
{
- __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
- XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
+ if (ctxt != NULL)
+ ctxt->error = XML_ERR_NO_MEMORY;
+
+ xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_C14N, NULL);
}
-/**
- * xmlC14NErrParam:
- * @extra: extra information
- *
- * Handle a redefinition of param error
- */
static void
-xmlC14NErrParam(const char *extra)
+xmlC14NErrFull(xmlC14NCtxPtr ctxt, xmlNodePtr node, int code, const char *str1,
+ const char *msg, ...)
{
- __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
- XML_ERR_INTERNAL_ERROR, XML_ERR_ERROR, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Invalid parameter : %s\n", extra);
+ va_list ap;
+ int res;
+
+ if (ctxt != NULL)
+ ctxt->error = code;
+
+ va_start(ap, msg);
+ res = xmlVRaiseError(NULL, NULL, NULL, ctxt, node,
+ XML_FROM_C14N, code, XML_ERR_ERROR, NULL, 0,
+ str1, NULL, NULL, 0, 0,
+ msg, ap);
+ va_end(ap);
+ if (res < 0)
+ xmlC14NErrMemory(ctxt);
}
/**
- * xmlC14NErrInternal:
+ * xmlC14NErrParam:
* @extra: extra information
*
- * Handle a redefinition of internal error
+ * Handle a param error
*/
static void
-xmlC14NErrInternal(const char *extra)
+xmlC14NErrParam(xmlC14NCtxPtr ctxt)
{
- __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
- XML_ERR_INTERNAL_ERROR, XML_ERR_ERROR, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Internal error : %s\n", extra);
+ xmlC14NErrFull(ctxt, NULL, XML_ERR_ARGUMENT, NULL,
+ "Invalid argument\n", NULL);
}
/**
* xmlC14NErrInvalidNode:
* @extra: extra information
*
- * Handle a redefinition of invalid node error
+ * Handle an invalid node error
*/
static void
-xmlC14NErrInvalidNode(const char *node_type, const char *extra)
+xmlC14NErrInvalidNode(xmlC14NCtxPtr ctxt, const char *node_type,
+ const char *extra)
{
- __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
- XML_C14N_INVALID_NODE, XML_ERR_ERROR, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Node %s is invalid here : %s\n", node_type, extra);
+ xmlC14NErrFull(ctxt, NULL, XML_C14N_INVALID_NODE, extra,
+ "Node %s is invalid here : %s\n", node_type, extra);
}
/**
* xmlC14NErrUnknownNode:
* @extra: extra information
*
- * Handle a redefinition of unknown node error
+ * Handle an unknown node error
*/
static void
-xmlC14NErrUnknownNode(int node_type, const char *extra)
+xmlC14NErrUnknownNode(xmlC14NCtxPtr ctxt, int node_type, const char *extra)
{
- __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
- XML_C14N_UNKNOW_NODE, XML_ERR_ERROR, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Unknown node type %d found : %s\n", node_type, extra);
+ xmlC14NErrFull(ctxt, NULL, XML_C14N_UNKNOW_NODE, extra,
+ "Unknown node type %d found : %s\n", node_type, extra);
}
/**
* xmlC14NErrRelativeNamespace:
* @extra: extra information
*
- * Handle a redefinition of relative namespace error
+ * Handle a relative namespace error
*/
static void
-xmlC14NErrRelativeNamespace(const char *ns_uri)
+xmlC14NErrRelativeNamespace(xmlC14NCtxPtr ctxt, const char *ns_uri)
{
- __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
- XML_C14N_RELATIVE_NAMESPACE, XML_ERR_ERROR, NULL, 0, NULL,
- NULL, NULL, 0, 0,
- "Relative namespace UR is invalid here : %s\n", ns_uri);
+ xmlC14NErrFull(ctxt, NULL, XML_C14N_RELATIVE_NAMESPACE, ns_uri,
+ "Relative namespace UR is invalid here : %s\n", ns_uri);
}
@@ -227,18 +225,13 @@ xmlC14NErrRelativeNamespace(const char *ns_uri)
* @msg: the message
* @extra: extra information
*
- * Handle a redefinition of attribute error
+ * Handle an error
*/
static void
xmlC14NErr(xmlC14NCtxPtr ctxt, xmlNodePtr node, int error,
const char * msg)
{
- if (ctxt != NULL)
- ctxt->error = error;
- __xmlRaiseError(NULL, NULL, NULL,
- ctxt, node, XML_FROM_C14N, error,
- XML_ERR_ERROR, NULL, 0,
- NULL, NULL, NULL, 0, 0, "%s", msg);
+ xmlC14NErrFull(ctxt, node, error, NULL, "%s", msg);
}
/************************************************************************
@@ -281,10 +274,8 @@ xmlC14NVisibleNsStackCreate(void) {
xmlC14NVisibleNsStackPtr ret;
ret = (xmlC14NVisibleNsStackPtr) xmlMalloc(sizeof(xmlC14NVisibleNsStack));
- if (ret == NULL) {
- xmlC14NErrMemory("creating namespaces stack");
+ if (ret == NULL)
return(NULL);
- }
memset(ret, 0, sizeof(xmlC14NVisibleNsStack));
return(ret);
}
@@ -292,7 +283,7 @@ xmlC14NVisibleNsStackCreate(void) {
static void
xmlC14NVisibleNsStackDestroy(xmlC14NVisibleNsStackPtr cur) {
if(cur == NULL) {
- xmlC14NErrParam("destroying namespaces stack");
+ xmlC14NErrParam(NULL);
return;
}
if(cur->nsTab != NULL) {
@@ -308,22 +299,18 @@ xmlC14NVisibleNsStackDestroy(xmlC14NVisibleNsStackPtr cur) {
}
-static void
+static int
xmlC14NVisibleNsStackAdd(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlNodePtr node) {
if((cur == NULL) ||
((cur->nsTab == NULL) && (cur->nodeTab != NULL)) ||
- ((cur->nsTab != NULL) && (cur->nodeTab == NULL))) {
- xmlC14NErrParam("adding namespace to stack");
- return;
- }
+ ((cur->nsTab != NULL) && (cur->nodeTab == NULL)))
+ return (1);
if ((cur->nsTab == NULL) && (cur->nodeTab == NULL)) {
cur->nsTab = (xmlNsPtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
cur->nodeTab = (xmlNodePtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
- if ((cur->nsTab == NULL) || (cur->nodeTab == NULL)) {
- xmlC14NErrMemory("adding node to stack");
- return;
- }
+ if ((cur->nsTab == NULL) || (cur->nodeTab == NULL))
+ return (-1);
memset(cur->nsTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
memset(cur->nodeTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
cur->nsMax = XML_NAMESPACES_DEFAULT;
@@ -333,17 +320,13 @@ xmlC14NVisibleNsStackAdd(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlNodePtr n
tmpSize = 2 * cur->nsMax;
tmp = xmlRealloc(cur->nsTab, tmpSize * sizeof(xmlNsPtr));
- if (tmp == NULL) {
- xmlC14NErrMemory("adding node to stack");
- return;
- }
+ if (tmp == NULL)
+ return (-1);
cur->nsTab = (xmlNsPtr*)tmp;
tmp = xmlRealloc(cur->nodeTab, tmpSize * sizeof(xmlNodePtr));
- if (tmp == NULL) {
- xmlC14NErrMemory("adding node to stack");
- return;
- }
+ if (tmp == NULL)
+ return (-1);
cur->nodeTab = (xmlNodePtr*)tmp;
cur->nsMax = tmpSize;
@@ -352,12 +335,14 @@ xmlC14NVisibleNsStackAdd(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlNodePtr n
cur->nodeTab[cur->nsCurEnd] = node;
++cur->nsCurEnd;
+
+ return (0);
}
static void
xmlC14NVisibleNsStackSave(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
if((cur == NULL) || (state == NULL)) {
- xmlC14NErrParam("saving namespaces stack");
+ xmlC14NErrParam(NULL);
return;
}
@@ -369,7 +354,7 @@ xmlC14NVisibleNsStackSave(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr
static void
xmlC14NVisibleNsStackRestore(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
if((cur == NULL) || (state == NULL)) {
- xmlC14NErrParam("restoring namespaces stack");
+ xmlC14NErrParam(NULL);
return;
}
cur->nsCurEnd = state->nsCurEnd;
@@ -380,7 +365,7 @@ xmlC14NVisibleNsStackRestore(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStack
static void
xmlC14NVisibleNsStackShift(xmlC14NVisibleNsStackPtr cur) {
if(cur == NULL) {
- xmlC14NErrParam("shifting namespaces stack");
+ xmlC14NErrParam(NULL);
return;
}
cur->nsPrevStart = cur->nsPrevEnd;
@@ -416,7 +401,7 @@ xmlC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns)
int has_empty_ns;
if(cur == NULL) {
- xmlC14NErrParam("searching namespaces stack (c14n)");
+ xmlC14NErrParam(NULL);
return (0);
}
@@ -449,7 +434,7 @@ xmlExcC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlC14NC
int has_empty_ns;
if(cur == NULL) {
- xmlC14NErrParam("searching namespaces stack (exc c14n)");
+ xmlC14NErrParam(ctx);
return (0);
}
@@ -513,8 +498,8 @@ xmlC14NIsXmlNs(xmlNsPtr ns)
static int
xmlC14NNsCompare(const void *data1, const void *data2)
{
- const xmlNsPtr ns1 = (const xmlNsPtr) data1;
- const xmlNsPtr ns2 = (const xmlNsPtr) data2;
+ const xmlNs *ns1 = data1;
+ const xmlNs *ns2 = data2;
if (ns1 == ns2)
return (0);
if (ns1 == NULL)
@@ -536,11 +521,11 @@ xmlC14NNsCompare(const void *data1, const void *data2)
* Returns 1 on success or 0 on fail.
*/
static int
-xmlC14NPrintNamespaces(const xmlNsPtr ns, xmlC14NCtxPtr ctx)
+xmlC14NPrintNamespaces(const xmlNs *ns, xmlC14NCtxPtr ctx)
{
if ((ns == NULL) || (ctx == NULL)) {
- xmlC14NErrParam("writing namespaces");
+ xmlC14NErrParam(ctx);
return 0;
}
@@ -552,7 +537,7 @@ xmlC14NPrintNamespaces(const xmlNsPtr ns, xmlC14NCtxPtr ctx)
xmlOutputBufferWriteString(ctx->buf, " xmlns=");
}
if(ns->href != NULL) {
- xmlBufWriteQuotedString(ctx->buf->buffer, ns->href);
+ xmlOutputBufferWriteQuotedString(ctx->buf, ns->href);
} else {
xmlOutputBufferWriteString(ctx->buf, "\"\"");
}
@@ -561,7 +546,7 @@ xmlC14NPrintNamespaces(const xmlNsPtr ns, xmlC14NCtxPtr ctx)
static int
xmlC14NPrintNamespacesWalker(const void *ns, void *ctx) {
- return xmlC14NPrintNamespaces((const xmlNsPtr) ns, (xmlC14NCtxPtr) ctx);
+ return xmlC14NPrintNamespaces(ns, ctx);
}
/**
@@ -613,7 +598,7 @@ xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
int has_empty_ns = 0;
if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
- xmlC14NErrParam("processing namespaces axis (c14n)");
+ xmlC14NErrParam(ctx);
return (-1);
}
@@ -622,7 +607,7 @@ xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
*/
list = xmlListCreate(NULL, xmlC14NNsCompare);
if (list == NULL) {
- xmlC14NErrInternal("creating namespaces list (c14n)");
+ xmlC14NErrMemory(ctx);
return (-1);
}
@@ -634,7 +619,10 @@ xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
if((tmp == ns) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
if(visible) {
- xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
+ if (xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur) < 0) {
+ xmlC14NErrMemory(ctx);
+ goto error;
+ }
}
if(!already_rendered) {
xmlListInsert(list, ns);
@@ -673,6 +661,7 @@ xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
/*
* Cleanup
*/
+error:
xmlListDelete(list);
return (0);
}
@@ -720,12 +709,12 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
int has_empty_ns_in_inclusive_list = 0;
if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
- xmlC14NErrParam("processing namespaces axis (exc c14n)");
+ xmlC14NErrParam(ctx);
return (-1);
}
if(!xmlC14NIsExclusive(ctx)) {
- xmlC14NErrParam("processing namespaces axis (exc c14n)");
+ xmlC14NErrParam(ctx);
return (-1);
}
@@ -735,7 +724,7 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
*/
list = xmlListCreate(NULL, xmlC14NNsCompare);
if (list == NULL) {
- xmlC14NErrInternal("creating namespaces list (exc c14n)");
+ xmlC14NErrMemory(ctx);
return (-1);
}
@@ -763,7 +752,10 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
if((ns != NULL) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
if(visible) {
- xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
+ if (xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur) < 0) {
+ xmlC14NErrMemory(ctx);
+ goto error;
+ }
}
if(!already_rendered) {
xmlListInsert(list, ns);
@@ -789,7 +781,10 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
}
}
if(visible) {
- xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
+ if (xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur) < 0) {
+ xmlC14NErrMemory(ctx);
+ goto error;
+ }
}
if(xmlStrlen(ns->prefix) == 0) {
has_empty_ns = 1;
@@ -806,7 +801,10 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
*/
if((attr->ns != NULL) && !xmlC14NIsXmlNs(attr->ns) && xmlC14NIsVisible(ctx, attr, cur)) {
already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, attr->ns, ctx);
- xmlC14NVisibleNsStackAdd(ctx->ns_rendered, attr->ns, cur);
+ if (xmlC14NVisibleNsStackAdd(ctx->ns_rendered, attr->ns, cur) < 0) {
+ xmlC14NErrMemory(ctx);
+ goto error;
+ }
if(!already_rendered && visible) {
xmlListInsert(list, attr->ns);
}
@@ -850,6 +848,7 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
/*
* Cleanup
*/
+error:
xmlListDelete(list);
return (0);
}
@@ -886,8 +885,8 @@ xmlC14NIsXmlAttr(xmlAttrPtr attr)
static int
xmlC14NAttrsCompare(const void *data1, const void *data2)
{
- const xmlAttrPtr attr1 = (const xmlAttrPtr) data1;
- const xmlAttrPtr attr2 = (const xmlAttrPtr) data2;
+ const xmlAttr *attr1 = data1;
+ const xmlAttr *attr2 = data2;
int ret = 0;
/*
@@ -940,13 +939,13 @@ xmlC14NAttrsCompare(const void *data1, const void *data2)
static int
xmlC14NPrintAttrs(const void *data, void *user)
{
- const xmlAttrPtr attr = (const xmlAttrPtr) data;
+ const xmlAttr *attr = data;
xmlC14NCtxPtr ctx = (xmlC14NCtxPtr) user;
xmlChar *value;
xmlChar *buffer;
if ((attr == NULL) || (ctx == NULL)) {
- xmlC14NErrParam("writing attributes");
+ xmlC14NErrParam(ctx);
return (0);
}
@@ -968,7 +967,7 @@ xmlC14NPrintAttrs(const void *data, void *user)
xmlOutputBufferWriteString(ctx->buf, (const char *) buffer);
xmlFree(buffer);
} else {
- xmlC14NErrInternal("normalizing attributes axis");
+ xmlC14NErrMemory(ctx);
return (0);
}
}
@@ -1017,20 +1016,22 @@ xmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
int tmp_str_len;
if ((ctx == NULL) || (xml_base_attr == NULL) || (xml_base_attr->parent == NULL)) {
- xmlC14NErrParam("processing xml:base attribute");
+ xmlC14NErrParam(ctx);
return (NULL);
}
/* start from current value */
res = xmlNodeListGetString(ctx->doc, xml_base_attr->children, 1);
if(res == NULL) {
- xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
+ xmlC14NErrMemory(ctx);
return (NULL);
}
/* go up the stack until we find a node that we rendered already */
cur = xml_base_attr->parent->parent;
while((cur != NULL) && (!xmlC14NIsVisible(ctx, cur, cur->parent))) {
+ int code;
+
attr = xmlHasNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
if(attr != NULL) {
/* get attr value */
@@ -1038,7 +1039,7 @@ xmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
if(tmp_str == NULL) {
xmlFree(res);
- xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
+ xmlC14NErrMemory(ctx);
return (NULL);
}
@@ -1051,7 +1052,7 @@ xmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
xmlFree(tmp_str);
xmlFree(res);
- xmlC14NErrInternal("processing xml:base attribute - can't modify uri");
+ xmlC14NErrMemory(ctx);
return (NULL);
}
@@ -1059,12 +1060,17 @@ xmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
}
/* build uri */
- tmp_str2 = xmlBuildURI(res, tmp_str);
- if(tmp_str2 == NULL) {
+ code = xmlBuildURISafe(res, tmp_str, &tmp_str2);
+ if (code != 0) {
xmlFree(tmp_str);
xmlFree(res);
- xmlC14NErrInternal("processing xml:base attribute - can't construct uri");
+ if (code < 0)
+ xmlC14NErrMemory(ctx);
+ else
+ xmlC14NErr(ctx, cur, XML_ERR_INVALID_URI,
+ "processing xml:base attribute - "
+ "can't construct uri");
return (NULL);
}
@@ -1089,7 +1095,7 @@ xmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
if(attr == NULL) {
xmlFree(res);
- xmlC14NErrInternal("processing xml:base attribute - can't construct attribute");
+ xmlC14NErrMemory(ctx);
return (NULL);
}
@@ -1144,7 +1150,7 @@ xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
xmlAttrPtr xml_space_attr = NULL;
if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
- xmlC14NErrParam("processing attributes axis");
+ xmlC14NErrParam(ctx);
return (-1);
}
@@ -1153,7 +1159,7 @@ xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
*/
list = xmlListCreate(NULL, xmlC14NAttrsCompare);
if (list == NULL) {
- xmlC14NErrInternal("creating attributes list");
+ xmlC14NErrMemory(ctx);
return (-1);
}
@@ -1365,7 +1371,7 @@ xmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur)
xmlNsPtr ns;
if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
- xmlC14NErrParam("checking for relative namespaces");
+ xmlC14NErrParam(ctx);
return (-1);
}
@@ -1373,14 +1379,19 @@ xmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur)
while (ns != NULL) {
if (xmlStrlen(ns->href) > 0) {
xmlURIPtr uri;
+ int code;
- uri = xmlParseURI((const char *) ns->href);
+ code = xmlParseURISafe((const char *) ns->href, &uri);
if (uri == NULL) {
- xmlC14NErrInternal("parsing namespace uri");
+ if (code < 0)
+ xmlC14NErrMemory(ctx);
+ else
+ xmlC14NErr(ctx, cur, XML_ERR_INVALID_URI,
+ "parsing namespace uri");
return (-1);
}
if (xmlStrlen((const xmlChar *) uri->scheme) == 0) {
- xmlC14NErrRelativeNamespace(uri->scheme);
+ xmlC14NErrRelativeNamespace(ctx, uri->scheme);
xmlFreeURI(uri);
return (-1);
}
@@ -1422,7 +1433,7 @@ xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
int parent_is_doc = 0;
if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
- xmlC14NErrParam("processing element node");
+ xmlC14NErrParam(ctx);
return (-1);
}
@@ -1431,11 +1442,8 @@ xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
* implementations of XML canonicalization MUST report an operation
* failure on documents containing relative namespace URIs.
*/
- if (xmlC14NCheckForRelativeNamespaces(ctx, cur) < 0) {
- xmlC14NErrInternal("checking for relative namespaces");
+ if (xmlC14NCheckForRelativeNamespaces(ctx, cur) < 0)
return (-1);
- }
-
/*
* Save ns_rendered stack position
@@ -1465,30 +1473,24 @@ xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
} else {
ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);
}
- if (ret < 0) {
- xmlC14NErrInternal("processing namespaces axis");
+ if (ret < 0)
return (-1);
- }
/* todo: shouldn't this go to "visible only"? */
if(visible) {
xmlC14NVisibleNsStackShift(ctx->ns_rendered);
}
ret = xmlC14NProcessAttrsAxis(ctx, cur, visible);
- if (ret < 0) {
- xmlC14NErrInternal("processing attributes axis");
+ if (ret < 0)
return (-1);
- }
if (visible) {
xmlOutputBufferWriteString(ctx->buf, ">");
}
if (cur->children != NULL) {
ret = xmlC14NProcessNodeList(ctx, cur->children);
- if (ret < 0) {
- xmlC14NErrInternal("processing childrens list");
+ if (ret < 0)
return (-1);
- }
}
if (visible) {
xmlOutputBufferWriteString(ctx->buf, "");
@@ -1529,7 +1531,7 @@ xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
int visible;
if ((ctx == NULL) || (cur == NULL)) {
- xmlC14NErrParam("processing node");
+ xmlC14NErrParam(ctx);
return (-1);
}
@@ -1558,7 +1560,7 @@ xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
(const char *) buffer);
xmlFree(buffer);
} else {
- xmlC14NErrInternal("normalizing text node");
+ xmlC14NErrMemory(ctx);
return (-1);
}
}
@@ -1597,7 +1599,7 @@ xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
(const char *) buffer);
xmlFree(buffer);
} else {
- xmlC14NErrInternal("normalizing pi node");
+ xmlC14NErrMemory(ctx);
return (-1);
}
}
@@ -1642,7 +1644,7 @@ xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
(const char *) buffer);
xmlFree(buffer);
} else {
- xmlC14NErrInternal("normalizing comment node");
+ xmlC14NErrMemory(ctx);
return (-1);
}
}
@@ -1667,16 +1669,16 @@ xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
break;
case XML_ATTRIBUTE_NODE:
- xmlC14NErrInvalidNode("XML_ATTRIBUTE_NODE", "processing node");
+ xmlC14NErrInvalidNode(ctx, "XML_ATTRIBUTE_NODE", "processing node");
return (-1);
case XML_NAMESPACE_DECL:
- xmlC14NErrInvalidNode("XML_NAMESPACE_DECL", "processing node");
+ xmlC14NErrInvalidNode(ctx, "XML_NAMESPACE_DECL", "processing node");
return (-1);
case XML_ENTITY_REF_NODE:
- xmlC14NErrInvalidNode("XML_ENTITY_REF_NODE", "processing node");
+ xmlC14NErrInvalidNode(ctx, "XML_ENTITY_REF_NODE", "processing node");
return (-1);
case XML_ENTITY_NODE:
- xmlC14NErrInvalidNode("XML_ENTITY_NODE", "processing node");
+ xmlC14NErrInvalidNode(ctx, "XML_ENTITY_NODE", "processing node");
return (-1);
case XML_DOCUMENT_TYPE_NODE:
@@ -1694,7 +1696,7 @@ xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
*/
break;
default:
- xmlC14NErrUnknownNode(cur->type, "processing node");
+ xmlC14NErrUnknownNode(ctx, cur->type, "processing node");
return (-1);
}
@@ -1716,7 +1718,7 @@ xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur)
int ret;
if (ctx == NULL) {
- xmlC14NErrParam("processing node list");
+ xmlC14NErrParam(ctx);
return (-1);
}
@@ -1738,7 +1740,7 @@ static void
xmlC14NFreeCtx(xmlC14NCtxPtr ctx)
{
if (ctx == NULL) {
- xmlC14NErrParam("freeing context");
+ xmlC14NErrParam(ctx);
return;
}
@@ -1778,7 +1780,7 @@ xmlC14NNewCtx(xmlDocPtr doc,
xmlC14NCtxPtr ctx = NULL;
if ((doc == NULL) || (buf == NULL)) {
- xmlC14NErrParam("creating new context");
+ xmlC14NErrParam(ctx);
return (NULL);
}
@@ -1796,7 +1798,7 @@ xmlC14NNewCtx(xmlDocPtr doc,
*/
ctx = (xmlC14NCtxPtr) xmlMalloc(sizeof(xmlC14NCtx));
if (ctx == NULL) {
- xmlC14NErrMemory("creating context");
+ xmlC14NErrMemory(ctx);
return (NULL);
}
memset(ctx, 0, sizeof(xmlC14NCtx));
@@ -1814,8 +1816,7 @@ xmlC14NNewCtx(xmlDocPtr doc,
ctx->ns_rendered = xmlC14NVisibleNsStackCreate();
if(ctx->ns_rendered == NULL) {
- xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_CREATE_STACK,
- "xmlC14NNewCtx: xmlC14NVisibleNsStackCreate failed\n");
+ xmlC14NErrMemory(ctx);
xmlC14NFreeCtx(ctx);
return (NULL);
}
@@ -1828,6 +1829,7 @@ xmlC14NNewCtx(xmlDocPtr doc,
if(xmlC14NIsExclusive(ctx)) {
ctx->inclusive_ns_prefixes = inclusive_ns_prefixes;
}
+
return (ctx);
}
@@ -1864,7 +1866,7 @@ xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
int ret;
if ((buf == NULL) || (doc == NULL)) {
- xmlC14NErrParam("executing c14n");
+ xmlC14NErrParam(NULL);
return (-1);
}
@@ -1877,7 +1879,7 @@ xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
c14n_mode = (xmlC14NMode)mode;
break;
default:
- xmlC14NErrParam("invalid mode for executing c14n");
+ xmlC14NErrParam(NULL);
return (-1);
}
@@ -1912,7 +1914,6 @@ xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
if (doc->children != NULL) {
ret = xmlC14NProcessNodeList(ctx, doc->children);
if (ret < 0) {
- xmlC14NErrInternal("processing docs children list");
xmlC14NFreeCtx(ctx);
return (-1);
}
@@ -1923,7 +1924,7 @@ xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
*/
ret = xmlOutputBufferFlush(buf);
if (ret < 0) {
- xmlC14NErrInternal("flushing output buffer");
+ xmlC14NErr(ctx, NULL, buf->error, "flushing output buffer");
xmlC14NFreeCtx(ctx);
return (-1);
}
@@ -2000,7 +2001,7 @@ xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
xmlOutputBufferPtr buf;
if (doc_txt_ptr == NULL) {
- xmlC14NErrParam("dumping doc to memory");
+ xmlC14NErrParam(NULL);
return (-1);
}
@@ -2011,7 +2012,7 @@ xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
*/
buf = xmlAllocOutputBuffer(NULL);
if (buf == NULL) {
- xmlC14NErrMemory("creating output buffer");
+ xmlC14NErrMemory(NULL);
return (-1);
}
@@ -2021,7 +2022,6 @@ xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
with_comments, buf);
if (ret < 0) {
- xmlC14NErrInternal("saving doc to output buffer");
(void) xmlOutputBufferClose(buf);
return (-1);
}
@@ -2033,7 +2033,7 @@ xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
(void) xmlOutputBufferClose(buf);
if ((*doc_txt_ptr == NULL) && (ret >= 0)) {
- xmlC14NErrMemory("copying canonicalized document");
+ xmlC14NErrMemory(NULL);
return (-1);
}
return (ret);
@@ -2071,7 +2071,7 @@ xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
int ret;
if (filename == NULL) {
- xmlC14NErrParam("saving doc");
+ xmlC14NErrParam(NULL);
return (-1);
}
#ifdef LIBXML_ZLIB_ENABLED
@@ -2084,7 +2084,7 @@ xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
*/
buf = xmlOutputBufferCreateFilename(filename, NULL, compression);
if (buf == NULL) {
- xmlC14NErrInternal("creating temporary filename");
+ xmlC14NErr(NULL, NULL, XML_IO_UNKNOWN, "creating temporary filename");
return (-1);
}
@@ -2094,7 +2094,6 @@ xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
with_comments, buf);
if (ret < 0) {
- xmlC14NErrInternal("canonize document to buffer");
(void) xmlOutputBufferClose(buf);
return (-1);
}
@@ -2106,21 +2105,6 @@ xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
return (ret);
}
-
-
-/*
- * Macro used to grow the current buffer.
- */
-#define growBufferReentrant() { \
- buffer_size *= 2; \
- buffer = (xmlChar *) \
- xmlRealloc(buffer, buffer_size); \
- if (buffer == NULL) { \
- xmlC14NErrMemory("growing buffer"); \
- return(NULL); \
- } \
-}
-
/**
* xmlC11NNormalizeString:
* @input: the input string
@@ -2150,17 +2134,22 @@ xmlC11NNormalizeString(const xmlChar * input,
*/
buffer_size = 1000;
buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
- if (buffer == NULL) {
- xmlC14NErrMemory("allocating buffer");
+ if (buffer == NULL)
return (NULL);
- }
out = buffer;
while (*cur != '\0') {
if ((out - buffer) > (buffer_size - 10)) {
+ xmlChar *tmp;
int indx = out - buffer;
- growBufferReentrant();
+ buffer_size *= 2;
+ tmp = xmlRealloc(buffer, buffer_size);
+ if (tmp == NULL) {
+ xmlFree(buffer);
+ return(NULL);
+ }
+ buffer = tmp;
out = &buffer[indx];
}
diff --git a/catalog.c b/catalog.c
index 33514d9..6a32c0f 100644
--- a/catalog.c
+++ b/catalog.c
@@ -16,6 +16,7 @@
#include "libxml.h"
#ifdef LIBXML_CATALOG_ENABLED
+#include
#include
#include
#ifdef HAVE_SYS_STAT_H
@@ -52,21 +53,6 @@
# define PATH_SEPARATOR ':'
#endif
-/**
- * TODO:
- *
- * macro to flag unimplemented blocks
- * XML_CATALOG_PREFER user env to select between system/public preferred
- * option. C.f. Richard Tobin
- *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
- *> values "system" and "public". I have made the default be "system" to
- *> match yours.
- */
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
#define XML_URN_PUBID "urn:publicid:"
#define XML_CATAL_BREAK ((xmlChar *) -1)
#ifndef XML_XML_DEFAULT_CATALOG
@@ -76,18 +62,6 @@
#define XML_SGML_DEFAULT_CATALOG "file://" SYSCONFDIR "/sgml/catalog"
#endif
-#if defined(_WIN32) && defined(_MSC_VER)
-#undef XML_XML_DEFAULT_CATALOG
-static char XML_XML_DEFAULT_CATALOG[256] = "file://" SYSCONFDIR "/xml/catalog";
-#if !defined(_WINDOWS_)
-void* __stdcall GetModuleHandleA(const char*);
-unsigned long __stdcall GetModuleFileNameA(void*, char*, unsigned long);
-#endif
-#endif
-
-static xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID);
-static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename);
-
/************************************************************************
* *
* Types, all private *
@@ -202,6 +176,21 @@ static xmlRMutexPtr xmlCatalogMutex = NULL;
*/
static int xmlCatalogInitialized = 0;
+/************************************************************************
+ * *
+ * Forward declarations *
+ * *
+ ************************************************************************/
+
+static xmlChar *
+xmlCatalogNormalizePublic(const xmlChar *pubID);
+
+static int
+xmlExpandCatalog(xmlCatalogPtr catal, const char *filename);
+
+static int
+xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal);
+
/************************************************************************
* *
* Catalog error handlers *
@@ -215,12 +204,9 @@ static int xmlCatalogInitialized = 0;
* Handle an out of memory condition
*/
static void
-xmlCatalogErrMemory(const char *extra)
+xmlCatalogErrMemory(void)
{
- __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_CATALOG,
- XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
- extra, NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
+ xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_CATALOG, NULL);
}
/**
@@ -237,11 +223,15 @@ xmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error,
const char *msg, const xmlChar *str1, const xmlChar *str2,
const xmlChar *str3)
{
- __xmlRaiseError(NULL, NULL, NULL, catal, node, XML_FROM_CATALOG,
- error, XML_ERR_ERROR, NULL, 0,
- (const char *) str1, (const char *) str2,
- (const char *) str3, 0, 0,
- msg, str1, str2, str3);
+ int res;
+
+ res = __xmlRaiseError(NULL, NULL, NULL, catal, node,
+ XML_FROM_CATALOG, error, XML_ERR_ERROR, NULL, 0,
+ (const char *) str1, (const char *) str2,
+ (const char *) str3, 0, 0,
+ msg, str1, str2, str3);
+ if (res < 0)
+ xmlCatalogErrMemory();
}
@@ -273,7 +263,7 @@ xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
if (ret == NULL) {
- xmlCatalogErrMemory("allocating catalog entry");
+ xmlCatalogErrMemory();
return(NULL);
}
ret->next = NULL;
@@ -331,13 +321,13 @@ xmlFreeCatalogEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
if (xmlDebugCatalogs) {
if (ret->name != NULL)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Free catalog entry %s\n", ret->name);
else if (ret->value != NULL)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Free catalog entry %s\n", ret->value);
else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Free catalog entry\n");
}
@@ -411,7 +401,7 @@ xmlCreateNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) {
ret = (xmlCatalogPtr) xmlMalloc(sizeof(xmlCatalog));
if (ret == NULL) {
- xmlCatalogErrMemory("allocating catalog");
+ xmlCatalogErrMemory();
return(NULL);
}
memset(ret, 0, sizeof(xmlCatalog));
@@ -551,6 +541,9 @@ static void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog,
case XML_CATA_BROKEN_CATALOG:
case XML_CATA_CATALOG:
if (cur == catal) {
+ if (cur->children == NULL) {
+ xmlFetchXMLCatalogFile(cur);
+ }
cur = cur->children;
continue;
}
@@ -795,7 +788,7 @@ xmlConvertSGMLCatalog(xmlCatalogPtr catal) {
return(-1);
if (xmlDebugCatalogs) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Converting SGML catalog to XML\n");
}
xmlHashScan(catal->sgml, xmlCatalogConvertEntry, &catal);
@@ -887,13 +880,12 @@ xmlDocPtr
xmlParseCatalogFile(const char *filename) {
xmlDocPtr ret;
xmlParserCtxtPtr ctxt;
- char *directory = NULL;
xmlParserInputPtr inputStream;
xmlParserInputBufferPtr buf;
ctxt = xmlNewParserCtxt();
if (ctxt == NULL) {
- xmlCatalogErrMemory("allocating parser context");
+ xmlCatalogErrMemory();
return(NULL);
}
@@ -915,10 +907,7 @@ xmlParseCatalogFile(const char *filename) {
xmlBufResetInput(buf->buffer, inputStream);
inputPush(ctxt, inputStream);
- if (ctxt->directory == NULL)
- directory = xmlParserGetDirectory(filename);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
+
ctxt->valid = 0;
ctxt->validate = 0;
ctxt->loadsubset = 0;
@@ -1012,7 +1001,7 @@ xmlLoadFileContent(const char *filename)
#endif
content = (xmlChar*)xmlMallocAtomic(size + 10);
if (content == NULL) {
- xmlCatalogErrMemory("allocating catalog data");
+ xmlCatalogErrMemory();
#ifdef HAVE_STAT
close(fd);
#else
@@ -1197,10 +1186,10 @@ xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
if (URL != NULL) {
if (xmlDebugCatalogs > 1) {
if (nameValue != NULL)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Found %s: '%s' '%s'\n", name, nameValue, URL);
else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Found %s: '%s'\n", name, URL);
}
ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer, cgroup);
@@ -1369,13 +1358,13 @@ xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {
doc = xmlParseCatalogFile((const char *) filename);
if (doc == NULL) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Failed to parse catalog %s\n", filename);
return(NULL);
}
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%d Parsing catalog %s\n", xmlGetThreadId(), filename);
cur = xmlDocGetRootElement(doc);
@@ -1448,7 +1437,7 @@ xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
if (doc != NULL) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Found %s in file hash\n", catal->URL);
if (catal->type == XML_CATA_CATALOG)
@@ -1460,7 +1449,7 @@ xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
return(0);
}
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s not found in file hash\n", catal->URL);
}
@@ -1487,7 +1476,7 @@ xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
xmlCatalogXMLFiles = xmlHashCreate(10);
if (xmlCatalogXMLFiles != NULL) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s added to file hash\n", catal->URL);
xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc);
}
@@ -1533,7 +1522,7 @@ xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
typ = xmlGetXMLCatalogEntryType(type);
if (typ == XML_CATA_NONE) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Failed to add unknown element %s to catalog\n", type);
return(-1);
}
@@ -1547,7 +1536,7 @@ xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
if ((orig != NULL) && (cur->type == typ) &&
(xmlStrEqual(orig, cur->name))) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Updating element %s to catalog\n", type);
if (cur->value != NULL)
xmlFree(cur->value);
@@ -1563,7 +1552,7 @@ xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
}
}
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Adding element %s to catalog\n", type);
if (cur == NULL)
catal->children = xmlNewCatalogEntry(typ, orig, replace,
@@ -1615,10 +1604,10 @@ xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
(xmlStrEqual(value, cur->value))) {
if (xmlDebugCatalogs) {
if (cur->name != NULL)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Removing element %s from catalog\n", cur->name);
else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Removing element %s from catalog\n", cur->value);
}
cur->type = XML_CATA_REMOVED;
@@ -1674,7 +1663,7 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
case XML_CATA_SYSTEM:
if (xmlStrEqual(sysID, cur->name)) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Found system match %s, using %s\n",
cur->name, cur->URL);
catal->depth--;
@@ -1703,7 +1692,7 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
}
if (rewrite != NULL) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Using rewriting rule %s\n", rewrite->name);
ret = xmlStrdup(rewrite->URL);
if (ret != NULL)
@@ -1738,7 +1727,7 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
}
if (cur->children != NULL) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Trying system delegate %s\n", cur->URL);
ret = xmlCatalogListXMLResolve(
cur->children, NULL, sysID);
@@ -1768,7 +1757,7 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
case XML_CATA_PUBLIC:
if (xmlStrEqual(pubID, cur->name)) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Found public match %s\n", cur->name);
catal->depth--;
return(xmlStrdup(cur->URL));
@@ -1817,7 +1806,7 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
}
if (cur->children != NULL) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Trying public delegate %s\n", cur->URL);
ret = xmlCatalogListXMLResolve(
cur->children, pubID, NULL);
@@ -1907,7 +1896,7 @@ xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
case XML_CATA_URI:
if (xmlStrEqual(URI, cur->name)) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Found URI match %s\n", cur->name);
return(xmlStrdup(cur->URL));
}
@@ -1934,7 +1923,7 @@ xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
}
if (rewrite != NULL) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Using rewriting rule %s\n", rewrite->name);
ret = xmlStrdup(rewrite->URL);
if (ret != NULL)
@@ -1969,7 +1958,7 @@ xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
}
if (cur->children != NULL) {
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Trying URI delegate %s\n", cur->URL);
ret = xmlCatalogListXMLResolveURI(
cur->children, URI);
@@ -2038,10 +2027,10 @@ xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
urnID = xmlCatalogUnWrapURN(pubID);
if (xmlDebugCatalogs) {
if (urnID == NULL)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Public URN ID %s expanded to NULL\n", pubID);
else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Public URN ID expanded to %s\n", urnID);
}
ret = xmlCatalogListXMLResolve(catal, urnID, sysID);
@@ -2055,10 +2044,10 @@ xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
urnID = xmlCatalogUnWrapURN(sysID);
if (xmlDebugCatalogs) {
if (urnID == NULL)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"System URN ID %s expanded to NULL\n", sysID);
else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"System URN ID expanded to %s\n", urnID);
}
if (pubID == NULL)
@@ -2122,10 +2111,10 @@ xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
urnID = xmlCatalogUnWrapURN(URI);
if (xmlDebugCatalogs) {
if (urnID == NULL)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"URN ID %s expanded to NULL\n", URI);
else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"URN ID expanded to %s\n", urnID);
}
ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
@@ -2212,7 +2201,7 @@ xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) {
}
buf = (xmlChar *) xmlMallocAtomic(size);
if (buf == NULL) {
- xmlCatalogErrMemory("allocating public ID");
+ xmlCatalogErrMemory();
return(NULL);
}
while (IS_PUBIDCHAR_CH(*cur) || (*cur == '?')) {
@@ -2224,7 +2213,7 @@ xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) {
size *= 2;
tmp = (xmlChar *) xmlRealloc(buf, size);
if (tmp == NULL) {
- xmlCatalogErrMemory("allocating public ID");
+ xmlCatalogErrMemory();
xmlFree(buf);
return(NULL);
}
@@ -2804,7 +2793,7 @@ xmlACatalogResolveSystem(xmlCatalogPtr catal, const xmlChar *sysID) {
return(NULL);
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Resolve sysID %s\n", sysID);
if (catal->type == XML_XML_CATALOG_TYPE) {
@@ -2839,7 +2828,7 @@ xmlACatalogResolvePublic(xmlCatalogPtr catal, const xmlChar *pubID) {
return(NULL);
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Resolve pubID %s\n", pubID);
if (catal->type == XML_XML_CATALOG_TYPE) {
@@ -2878,13 +2867,13 @@ xmlACatalogResolve(xmlCatalogPtr catal, const xmlChar * pubID,
if (xmlDebugCatalogs) {
if ((pubID != NULL) && (sysID != NULL)) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Resolve: pubID %s sysID %s\n", pubID, sysID);
} else if (pubID != NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Resolve: pubID %s\n", pubID);
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Resolve: sysID %s\n", sysID);
}
}
@@ -2921,7 +2910,7 @@ xmlACatalogResolveURI(xmlCatalogPtr catal, const xmlChar *URI) {
return(NULL);
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Resolve URI %s\n", URI);
if (catal->type == XML_XML_CATALOG_TYPE) {
@@ -3138,35 +3127,7 @@ xmlInitializeCatalog(void) {
catalogs = (const char *) getenv("XML_CATALOG_FILES");
if (catalogs == NULL)
-#if defined(_WIN32) && defined(_MSC_VER)
- {
- void* hmodule;
- hmodule = GetModuleHandleA("libxml2.dll");
- if (hmodule == NULL)
- hmodule = GetModuleHandleA(NULL);
- if (hmodule != NULL) {
- char buf[256];
- unsigned long len = GetModuleFileNameA(hmodule, buf, 255);
- if (len != 0) {
- char* p = &(buf[len]);
- while (*p != '\\' && p > buf)
- p--;
- if (p != buf) {
- xmlChar* uri;
- strncpy(p, "\\..\\etc\\catalog", 255 - (p - buf));
- uri = xmlCanonicPath((const xmlChar*)buf);
- if (uri != NULL) {
- strncpy(XML_XML_DEFAULT_CATALOG, (char* )uri, 255);
- xmlFree(uri);
- }
- }
- }
- }
- catalogs = XML_XML_DEFAULT_CATALOG;
- }
-#else
catalogs = XML_XML_DEFAULT_CATALOG;
-#endif
catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
xmlCatalogDefaultPrefer);
@@ -3298,7 +3259,7 @@ xmlCatalogCleanup(void) {
xmlRMutexLock(xmlCatalogMutex);
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Catalogs cleanup\n");
if (xmlCatalogXMLFiles != NULL)
xmlHashFree(xmlCatalogXMLFiles, xmlFreeCatalogHashEntryList);
@@ -3526,19 +3487,19 @@ xmlCatalogSetDefaults(xmlCatalogAllow allow) {
if (xmlDebugCatalogs) {
switch (allow) {
case XML_CATA_ALLOW_NONE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Disabling catalog usage\n");
break;
case XML_CATA_ALLOW_GLOBAL:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Allowing only global catalogs\n");
break;
case XML_CATA_ALLOW_DOCUMENT:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Allowing only catalogs from the document\n");
break;
case XML_CATA_ALLOW_ALL:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Allowing all catalogs\n");
break;
}
@@ -3566,11 +3527,11 @@ xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) {
if (xmlDebugCatalogs) {
switch (prefer) {
case XML_CATA_PREFER_PUBLIC:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Setting catalog preference to PUBLIC\n");
break;
case XML_CATA_PREFER_SYSTEM:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Setting catalog preference to SYSTEM\n");
break;
default:
@@ -3646,7 +3607,7 @@ xmlCatalogAddLocal(void *catalogs, const xmlChar *URL) {
return(catalogs);
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Adding document catalog %s\n", URL);
add = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, URL, NULL,
@@ -3690,13 +3651,13 @@ xmlCatalogLocalResolve(void *catalogs, const xmlChar *pubID,
if (xmlDebugCatalogs) {
if ((pubID != NULL) && (sysID != NULL)) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Local Resolve: pubID %s sysID %s\n", pubID, sysID);
} else if (pubID != NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Local Resolve: pubID %s\n", pubID);
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Local Resolve: sysID %s\n", sysID);
}
}
@@ -3733,7 +3694,7 @@ xmlCatalogLocalResolveURI(void *catalogs, const xmlChar *URI) {
return(NULL);
if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Resolve URI %s\n", URI);
catal = (xmlCatalogEntryPtr) catalogs;
@@ -3769,7 +3730,7 @@ xmlCatalogGetSystem(const xmlChar *sysID) {
xmlInitializeCatalog();
if (msg == 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Use of deprecated xmlCatalogGetSystem() call\n");
msg++;
}
@@ -3813,7 +3774,7 @@ xmlCatalogGetPublic(const xmlChar *pubID) {
xmlInitializeCatalog();
if (msg == 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Use of deprecated xmlCatalogGetPublic() call\n");
msg++;
}
diff --git a/debugXML.c b/debugXML.c
index 303515e..ed56b0f 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -154,31 +154,21 @@ static void
xmlDebugErr(xmlDebugCtxtPtr ctxt, int error, const char *msg)
{
ctxt->errors++;
- __xmlRaiseError(NULL, NULL, NULL,
- NULL, ctxt->node, XML_FROM_CHECK,
- error, XML_ERR_ERROR, NULL, 0,
- NULL, NULL, NULL, 0, 0,
- "%s", msg);
+ fprintf(ctxt->output, "ERROR %d: %s", error, msg);
}
static void LIBXML_ATTR_FORMAT(3,0)
xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra)
{
ctxt->errors++;
- __xmlRaiseError(NULL, NULL, NULL,
- NULL, ctxt->node, XML_FROM_CHECK,
- error, XML_ERR_ERROR, NULL, 0,
- NULL, NULL, NULL, 0, 0,
- msg, extra);
+ fprintf(ctxt->output, "ERROR %d: ", error);
+ fprintf(ctxt->output, msg, extra);
}
static void LIBXML_ATTR_FORMAT(3,0)
xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra)
{
ctxt->errors++;
- __xmlRaiseError(NULL, NULL, NULL,
- NULL, ctxt->node, XML_FROM_CHECK,
- error, XML_ERR_ERROR, NULL, 0,
- NULL, NULL, NULL, 0, 0,
- msg, extra);
+ fprintf(ctxt->output, "ERROR %d: ", error);
+ fprintf(ctxt->output, msg, extra);
}
/**
@@ -1824,47 +1814,47 @@ xmlShellPrintXPathError(int errorType, const char *arg)
switch (errorType) {
case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s: no such node\n", arg);
break;
case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s is a Boolean\n", arg);
break;
case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s is a number\n", arg);
break;
case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s is a string\n", arg);
break;
#ifdef LIBXML_XPTR_LOCS_ENABLED
case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s is a point\n", arg);
break;
case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s is a range\n", arg);
break;
case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s is a range\n", arg);
break;
#endif /* LIBXML_XPTR_LOCS_ENABLED */
case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s is user-defined\n", arg);
break;
case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s is an XSLT value tree\n", arg);
break;
}
#if 0
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Try casting the result string function (xpath builtin)\n",
arg);
#endif
@@ -1940,26 +1930,26 @@ xmlShellPrintXPathResultCtxt(xmlShellCtxtPtr ctxt,xmlXPathObjectPtr list)
list->nodesetval->nodeTab[indx]);
}
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Empty node set\n");
}
break;
#else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Node set\n");
#endif /* LIBXML_OUTPUT_ENABLED */
}
case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Is a Boolean:%s\n",
xmlBoolToText(list->boolval));
break;
case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Is a number:%0g\n", list->floatval);
break;
case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Is a string:%s\n", list->stringval);
break;
@@ -2331,6 +2321,16 @@ xmlShellSetContent(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
return (0);
}
+static void
+xmlShellPrintf(void *ctx, const char *msg, ...) {
+ xmlShellCtxtPtr sctxt = ctx;
+ va_list ap;
+
+ va_start(ap, msg);
+ vfprintf(sctxt->output, msg, ap);
+ va_end(ap);
+}
+
#ifdef LIBXML_SCHEMAS_ENABLED
/**
* xmlShellRNGValidate:
@@ -2355,23 +2355,23 @@ xmlShellRNGValidate(xmlShellCtxtPtr sctxt, char *schemas,
int ret;
ctxt = xmlRelaxNGNewParserCtxt(schemas);
- xmlRelaxNGSetParserErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
+ xmlRelaxNGSetParserErrors(ctxt, xmlShellPrintf, xmlShellPrintf, sctxt);
relaxngschemas = xmlRelaxNGParse(ctxt);
xmlRelaxNGFreeParserCtxt(ctxt);
if (relaxngschemas == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(sctxt->output,
"Relax-NG schema %s failed to compile\n", schemas);
return(-1);
}
vctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
- xmlRelaxNGSetValidErrors(vctxt, xmlGenericError, xmlGenericError, NULL);
+ xmlRelaxNGSetValidErrors(vctxt, xmlShellPrintf, xmlShellPrintf, sctxt);
ret = xmlRelaxNGValidateDoc(vctxt, sctxt->doc);
if (ret == 0) {
- fprintf(stderr, "%s validates\n", sctxt->filename);
+ fprintf(sctxt->output, "%s validates\n", sctxt->filename);
} else if (ret > 0) {
- fprintf(stderr, "%s fails to validate\n", sctxt->filename);
+ fprintf(sctxt->output, "%s fails to validate\n", sctxt->filename);
} else {
- fprintf(stderr, "%s validation generated an internal error\n",
+ fprintf(sctxt->output, "%s validation generated an internal error\n",
sctxt->filename);
}
xmlRelaxNGFreeValidCtxt(vctxt);
@@ -2506,7 +2506,7 @@ xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
}
#ifdef W_OK
if (access((char *) filename, W_OK)) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Cannot write to %s\n", filename);
return (-1);
}
@@ -2514,7 +2514,7 @@ xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
switch (node->type) {
case XML_DOCUMENT_NODE:
if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Failed to write to %s\n", filename);
return (-1);
}
@@ -2522,13 +2522,13 @@ xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
case XML_HTML_DOCUMENT_NODE:
#ifdef LIBXML_HTML_ENABLED
if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Failed to write to %s\n", filename);
return (-1);
}
#else
if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Failed to write to %s\n", filename);
return (-1);
}
@@ -2539,7 +2539,7 @@ xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
f = fopen((char *) filename, "w");
if (f == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Failed to write to %s\n", filename);
return (-1);
}
@@ -2575,7 +2575,7 @@ xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
return (-1);
#ifdef W_OK
if (access((char *) filename, W_OK)) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Cannot save to %s\n", filename);
return (-1);
}
@@ -2583,25 +2583,25 @@ xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
switch (ctxt->doc->type) {
case XML_DOCUMENT_NODE:
if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Failed to save to %s\n", filename);
}
break;
case XML_HTML_DOCUMENT_NODE:
#ifdef LIBXML_HTML_ENABLED
if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Failed to save to %s\n", filename);
}
#else
if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Failed to save to %s\n", filename);
}
#endif /* LIBXML_HTML_ENABLED */
break;
default:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"To save to subparts of a document use the 'write' command\n");
return (-1);
@@ -2634,8 +2634,9 @@ xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd,
if ((ctxt == NULL) || (ctxt->doc == NULL)) return(-1);
memset(&vctxt, 0, sizeof(vctxt));
- vctxt.error = xmlGenericError;
- vctxt.warning = xmlGenericError;
+ vctxt.error = xmlShellPrintf;
+ vctxt.warning = xmlShellPrintf;
+ vctxt.userData = ctxt;
if ((dtd == NULL) || (dtd[0] == 0)) {
res = xmlValidateDocument(&vctxt, ctxt->doc);
@@ -2791,7 +2792,7 @@ xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
* using a environment similar to a UNIX commandline.
*/
void
-xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
+xmlShell(xmlDocPtr doc, const char *filename, xmlShellReadlineFunc input,
FILE * output)
{
char prompt[500] = "/ > ";
@@ -2936,22 +2937,13 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
xmlShellSave(ctxt, arg, NULL, NULL);
} else if (!strcmp(command, "write")) {
if (arg[0] == 0)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Write command requires a filename argument\n");
else
xmlShellWrite(ctxt, arg, ctxt->node, NULL);
#endif /* LIBXML_OUTPUT_ENABLED */
} else if (!strcmp(command, "grep")) {
xmlShellGrep(ctxt, arg, ctxt->node, NULL);
- } else if (!strcmp(command, "free")) {
- if (arg[0] == 0) {
- xmlMemShow(ctxt->output, 0);
- } else {
- int len = 0;
-
- sscanf(arg, "%d", &len);
- xmlMemShow(ctxt->output, len);
- }
} else if (!strcmp(command, "pwd")) {
char dir[500];
@@ -2971,7 +2963,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
if (list != NULL) {
switch (list->type) {
case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
break;
case XPATH_NODESET:{
@@ -2989,37 +2981,37 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
break;
}
case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a Boolean\n", arg);
break;
case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a number\n", arg);
break;
case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a string\n", arg);
break;
#ifdef LIBXML_XPTR_LOCS_ENABLED
case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a point\n", arg);
break;
case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
#endif /* LIBXML_XPTR_LOCS_ENABLED */
case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is user-defined\n", arg);
break;
case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is an XSLT value tree\n",
arg);
break;
@@ -3028,7 +3020,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
xmlXPathFreeObject(list);
#endif
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
}
ctxt->pctxt->node = NULL;
@@ -3040,7 +3032,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
#ifdef LIBXML_XPATH_ENABLED
} else if (!strcmp(command, "setns")) {
if (arg[0] == 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"setns: prefix=[nsuri] required\n");
} else {
xmlShellRegisterNamespace(ctxt, arg, NULL, NULL);
@@ -3052,7 +3044,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
xmlShellRegisterRootNamespaces(ctxt, NULL, root, NULL);
} else if (!strcmp(command, "xpath")) {
if (arg[0] == 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"xpath: expression required\n");
} else {
ctxt->pctxt->node = ctxt->node;
@@ -3084,7 +3076,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
if (list != NULL) {
switch (list->type) {
case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
break;
case XPATH_NODESET:{
@@ -3108,37 +3100,37 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
break;
}
case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a Boolean\n", arg);
break;
case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a number\n", arg);
break;
case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a string\n", arg);
break;
#ifdef LIBXML_XPTR_LOCS_ENABLED
case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a point\n", arg);
break;
case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
#endif /* LIBXML_XPTR_LOCS_ENABLED */
case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is user-defined\n", arg);
break;
case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is an XSLT value tree\n",
arg);
break;
@@ -3147,7 +3139,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
xmlXPathFreeObject(list);
#endif
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
}
ctxt->pctxt->node = NULL;
@@ -3168,7 +3160,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
if (list != NULL) {
switch (list->type) {
case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
break;
case XPATH_NODESET:{
@@ -3187,37 +3179,37 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
break;
}
case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a Boolean\n", arg);
break;
case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a number\n", arg);
break;
case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a string\n", arg);
break;
#ifdef LIBXML_XPTR_LOCS_ENABLED
case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a point\n", arg);
break;
case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
#endif /* LIBXML_XPTR_LOCS_ENABLED */
case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is user-defined\n", arg);
break;
case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is an XSLT value tree\n",
arg);
break;
@@ -3226,7 +3218,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
xmlXPathFreeObject(list);
#endif
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
}
ctxt->pctxt->node = NULL;
@@ -3249,7 +3241,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
if (list != NULL) {
switch (list->type) {
case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
break;
case XPATH_NODESET:
@@ -3259,52 +3251,52 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
if ((ctxt->node != NULL) &&
(ctxt->node->type ==
XML_NAMESPACE_DECL)) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"cannot cd to namespace\n");
ctxt->node = NULL;
}
} else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a %d Node Set\n",
arg,
list->nodesetval->nodeNr);
} else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is an empty Node Set\n",
arg);
break;
case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a Boolean\n", arg);
break;
case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a number\n", arg);
break;
case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a string\n", arg);
break;
#ifdef LIBXML_XPTR_LOCS_ENABLED
case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a point\n", arg);
break;
case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
#endif /* LIBXML_XPTR_LOCS_ENABLED */
case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is user-defined\n", arg);
break;
case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is an XSLT value tree\n",
arg);
break;
@@ -3313,7 +3305,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
xmlXPathFreeObject(list);
#endif
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
}
ctxt->pctxt->node = NULL;
@@ -3333,7 +3325,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
if (list != NULL) {
switch (list->type) {
case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
break;
case XPATH_NODESET:{
@@ -3354,37 +3346,37 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
break;
}
case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a Boolean\n", arg);
break;
case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a number\n", arg);
break;
case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a string\n", arg);
break;
#ifdef LIBXML_XPTR_LOCS_ENABLED
case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a point\n", arg);
break;
case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is a range\n", arg);
break;
#endif /* LIBXML_XPTR_LOCS_ENABLED */
case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is user-defined\n", arg);
break;
case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s is an XSLT value tree\n",
arg);
break;
@@ -3393,14 +3385,14 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
xmlXPathFreeObject(list);
#endif
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"%s: no such node\n", arg);
}
ctxt->pctxt->node = NULL;
}
#endif /* LIBXML_OUTPUT_ENABLED */
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ctxt->output,
"Unknown command %s\n", command);
}
free(cmdline); /* not xmlFree here ! */
diff --git a/dict.c b/dict.c
index d7156ed..7d2be5e 100644
--- a/dict.c
+++ b/dict.c
@@ -19,11 +19,13 @@
#define IN_LIBXML
#include "libxml.h"
+#include
#include
+#include
#include
-#include
#include "private/dict.h"
+#include "private/globals.h"
#include "private/threads.h"
#include
@@ -508,6 +510,15 @@ xmlDictHashQName(unsigned seed, const xmlChar *prefix, const xmlChar *name,
return(h2 | MAX_HASH_SIZE);
}
+/**
+ * xmlDictComputeHash:
+ * @dict: dictionary
+ * @string: C string
+ *
+ * Compute the hash value of a C string.
+ *
+ * Returns the hash value.
+ */
unsigned
xmlDictComputeHash(const xmlDict *dict, const xmlChar *string) {
size_t len;
@@ -516,6 +527,15 @@ xmlDictComputeHash(const xmlDict *dict, const xmlChar *string) {
#define HASH_ROL31(x,n) ((x) << (n) | ((x) & 0x7FFFFFFF) >> (31 - (n)))
+/**
+ * xmlDictCombineHash:
+ * @v1: first hash value
+ * @v2: second hash value
+ *
+ * Combine two hash values.
+ *
+ * Returns the combined hash value.
+ */
ATTRIBUTE_NO_SANITIZE_INTEGER
unsigned
xmlDictCombineHash(unsigned v1, unsigned v2) {
@@ -904,30 +924,79 @@ xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
* Pseudo-random generator
*/
+#ifdef _WIN32
+ #define WIN32_LEAN_AND_MEAN
+ #include
+ #include
+ #ifdef _MSC_VER
+ #pragma comment(lib, "bcrypt.lib")
+ #endif
+#elif defined(HAVE_GETENTROPY)
+ #ifdef HAVE_UNISTD_H
+ #include
+ #endif
+ #ifdef HAVE_SYS_RANDOM_H
+ #include
+ #endif
+#else
+ #include
+#endif
+
static xmlMutex xmlRngMutex;
static unsigned globalRngState[2];
-#ifdef XML_THREAD_LOCAL
-static XML_THREAD_LOCAL int localRngInitialized = 0;
-static XML_THREAD_LOCAL unsigned localRngState[2];
-#endif
-
+/*
+ * xmlInitRandom:
+ *
+ * Initialize the PRNG.
+ */
ATTRIBUTE_NO_SANITIZE_INTEGER
void
xmlInitRandom(void) {
- int var;
-
xmlInitMutex(&xmlRngMutex);
- /* TODO: Get seed values from system PRNG */
-
- globalRngState[0] = (unsigned) time(NULL) ^
- HASH_ROL((unsigned) (size_t) &xmlInitRandom, 8);
- globalRngState[1] = HASH_ROL((unsigned) (size_t) &xmlRngMutex, 16) ^
- HASH_ROL((unsigned) (size_t) &var, 24);
+ {
+#ifdef _WIN32
+ NTSTATUS status;
+
+ status = BCryptGenRandom(NULL, (unsigned char *) globalRngState,
+ sizeof(globalRngState),
+ BCRYPT_USE_SYSTEM_PREFERRED_RNG);
+ if (!BCRYPT_SUCCESS(status)) {
+ fprintf(stderr, "libxml2: BCryptGenRandom failed with "
+ "error code %lu\n", GetLastError());
+ abort();
+ }
+#elif defined(HAVE_GETENTROPY)
+ while (1) {
+ if (getentropy(globalRngState, sizeof(globalRngState)) == 0)
+ break;
+
+ if (errno != EINTR) {
+ fprintf(stderr, "libxml2: getentropy failed with "
+ "error code %d\n", errno);
+ abort();
+ }
+ }
+#else
+ int var;
+
+ globalRngState[0] =
+ (unsigned) time(NULL) ^
+ HASH_ROL((unsigned) ((size_t) &xmlInitRandom & 0xFFFFFFFF), 8);
+ globalRngState[1] =
+ HASH_ROL((unsigned) ((size_t) &xmlRngMutex & 0xFFFFFFFF), 16) ^
+ HASH_ROL((unsigned) ((size_t) &var & 0xFFFFFFFF), 24);
+#endif
+ }
}
+/*
+ * xmlCleanupRandom:
+ *
+ * Clean up PRNG globals.
+ */
void
xmlCleanupRandom(void) {
xmlCleanupMutex(&xmlRngMutex);
@@ -947,19 +1016,15 @@ xoroshiro64ss(unsigned *s) {
return(result & 0xFFFFFFFF);
}
+/*
+ * xmlGlobalRandom:
+ *
+ * Generate a pseudo-random value using the global PRNG.
+ *
+ * Returns a random value.
+ */
unsigned
-xmlRandom(void) {
-#ifdef XML_THREAD_LOCAL
- if (!localRngInitialized) {
- xmlMutexLock(&xmlRngMutex);
- localRngState[0] = xoroshiro64ss(globalRngState);
- localRngState[1] = xoroshiro64ss(globalRngState);
- localRngInitialized = 1;
- xmlMutexUnlock(&xmlRngMutex);
- }
-
- return(xoroshiro64ss(localRngState));
-#else
+xmlGlobalRandom(void) {
unsigned ret;
xmlMutexLock(&xmlRngMutex);
@@ -967,6 +1032,21 @@ xmlRandom(void) {
xmlMutexUnlock(&xmlRngMutex);
return(ret);
+}
+
+/*
+ * xmlRandom:
+ *
+ * Generate a pseudo-random value using the thread-local PRNG.
+ *
+ * Returns a random value.
+ */
+unsigned
+xmlRandom(void) {
+#ifdef LIBXML_THREAD_ENABLED
+ return(xoroshiro64ss(xmlGetLocalRngState()));
+#else
+ return(xmlGlobalRandom());
#endif
}
diff --git a/distfiles/download.url b/distfiles/download.url
index 9bb41de..2682ffb 100644
--- a/distfiles/download.url
+++ b/distfiles/download.url
@@ -1 +1 @@
-https://download.gnome.org/sources/libxml2/2.12/libxml2-2.12.8.tar.xz
+https://download.gnome.org/sources/libxml2/2.13/libxml2-2.13.0.tar.xz
diff --git a/distfiles/libxml2-2.12.8-import.md5 b/distfiles/libxml2-2.12.8-import.md5
deleted file mode 100644
index d6ed4f8..0000000
--- a/distfiles/libxml2-2.12.8-import.md5
+++ /dev/null
@@ -1,138 +0,0 @@
-fec7ecfe714722b2bb0aaff7d200c701 Copyright
-7f7555dd7a030f5150fd0c3c32f7462a HTMLparser.c
-ac5d42c343d2093d2a031f59036c5f99 HTMLtree.c
-dd63184811cb2ff705c3e466364d3773 INSTALL
-bf65af783672f87d344a98c41d010184 NEWS
-d52aad5f8ace0ed3e5f9b126d72473e1 README.libxml2.md
-7283878f36a935a3c00df077cf45af54 SAX.c
-09a9556a3b8677675bd45ba603376aa0 SAX2.c
-57a293f421ac339af8ceaf40bfa461a6 buf.c
-9de80ca09b5855ff9817f90b741452e4 c14n.c
-0d7ba01913e22fd832d634c862fc1716 catalog.c
-691708e81dee605336b6ef6e431c5c21 chvalid.c
-fa4c7d0b18fba04f8458ed1b21ea563a debugXML.c
-d1071113f634435266c21de0bffc0315 dict.c
-10a103a4ea5dce7e3906291f958b7e9f encoding.c
-83e8ff3c5b69908c4a93357bdc60e91c entities.c
-bbb4bd2d42423b727ef64d7ce71611f6 error.c
-d9d2840f8f9f3e7f5ca35862bfeebf97 globals.c
-33d90ee08788d335c459779c0c5fd6e5 hash.c
-c3cd3bf7e9b4c37de582641b614cf6e8 include/libxml/HTMLparser.h
-bb4e2df91d33306ab3c2d71374559877 include/libxml/HTMLtree.h
-44e6202b2e65e38c48a5cacb75afe5bf include/libxml/SAX.h
-2f6eb29ddd29a6380634e0ba4757f102 include/libxml/SAX2.h
-dbcef76d0839253958697a919ddeea31 include/libxml/c14n.h
-17bea9cec4f3b2fb59a68af652c27ad8 include/libxml/catalog.h
-5b94bc432b4ab477a11761182334b646 include/libxml/chvalid.h
-79bb0a2a5b7cde377bb215214d0ea6d6 include/libxml/debugXML.h
-d00de0e505d1b4dfcccf9ff38837b61a include/libxml/dict.h
-e567122520ed052588fd6469f2efbc59 include/libxml/encoding.h
-b083ed530f79f607acbc1012281852d7 include/libxml/entities.h
-bc51344e21f8d3b7f0fc93cc9d554243 include/libxml/globals.h
-480b0bd8dded0583369dd8a4be21d450 include/libxml/hash.h
-6c03428a747fbfab599d4e86dd17d6b1 include/libxml/list.h
-d5c907a6d7d205e286168e007f32504c include/libxml/nanoftp.h
-3f166ef07a961ee21d3561682d859edc include/libxml/nanohttp.h
-715cf856fa05e7633b1254edfa0a45f4 include/libxml/parser.h
-36c2360e8bdaac08bfccba24e461d07f include/libxml/parserInternals.h
-f1afd2d52bf66fbf45f02dc35c72c3eb include/libxml/pattern.h
-d752e41ee40c2b028d0adb34ffc38810 include/libxml/relaxng.h
-853377a2dbf74e9b0d679dcfcc1859b9 include/libxml/schemasInternals.h
-7a163ee849171ffc2471a89704a33643 include/libxml/schematron.h
-84310bd67922e532329432f7ab04338c include/libxml/threads.h
-8508e1498b7772ae84baf83ddd33b65c include/libxml/tree.h
-9e795965522a7b231084cbd5ab089eda include/libxml/uri.h
-f26be264a608ed72fb7c74de76e3be72 include/libxml/valid.h
-d02d257861d28021ad33dad20e2683c3 include/libxml/xinclude.h
-4c7ff0fcbc3595d38f47e41f703dbc61 include/libxml/xlink.h
-ef62ebccc685b9bb49f75feab0b2ddd0 include/libxml/xmlIO.h
-78602d66c5db00b0deece2c56ab86d43 include/libxml/xmlautomata.h
-e3fe66a1c3ca6359481c0a4fa25491c6 include/libxml/xmlerror.h
-dc29dad477ae3b1779f8b15fbae14a0d include/libxml/xmlexports.h
-8eccb2172800caa343515fc0da596f4c include/libxml/xmlmemory.h
-1dda0f8301c72cab8c0015a4f36d008f include/libxml/xmlmodule.h
-abf4f7189ba11d03e73e22f9d1662328 include/libxml/xmlreader.h
-5f98d803fb4dd3fda837e2f922ce4e6a include/libxml/xmlregexp.h
-2183378075a4a69030b3280c1fd2d1c0 include/libxml/xmlsave.h
-f4c5548787cac73cd7c6d18a07555393 include/libxml/xmlschemas.h
-ac3b6d0c4a6fc4ea9fea5652b46b2992 include/libxml/xmlschemastypes.h
-74cf81ae5e6c6b553e49683528d78b6b include/libxml/xmlstring.h
-dbc8d631b733e9d36151f71e1230a9df include/libxml/xmlunicode.h
-33e2c97626678a66adb889aea827276e include/libxml/xmlwriter.h
-416bba8961630e597719243786393e4e include/libxml/xpath.h
-348e82b05d463eca3d661e2cc2db9aee include/libxml/xpathInternals.h
-74590f782d9b322ce115d1530e6f74d6 include/libxml/xpointer.h
-0abe699b64ec5d5776977857ce0f5af1 include/private/buf.h
-8ebef62d338f9d16691e061fc1fb5a9b include/private/dict.h
-ef188f33103bfaa4728d4d2fb885f67a include/private/enc.h
-5c2c0c5dd8609f827bad0dd5949b441e include/private/entities.h
-6e7e3b6e29613e28499dcf5e8ba63244 include/private/error.h
-40217f6d8ee2331ef3da4c894303d217 include/private/globals.h
-75db2838e28a9521292c484ccbb63fed include/private/html.h
-cccd6f58b21ed284f20a2063fc11751b include/private/io.h
-365385352b21fd09182380def0b8b7b5 include/private/memory.h
-8e95420939ee2c4d5f33456e7643d76f include/private/parser.h
-6188856c04348a92a5388d5176d7d016 include/private/regexp.h
-6c05f0bbe213b8b73b0e1028ba458973 include/private/save.h
-3b2905ef972b4faf312b39ceb490464d include/private/string.h
-a4976b987498c427b83793894d46fbed include/private/threads.h
-87384fd1fad9ab1259cbe92ee072f53d include/private/tree.h
-aa8f6d446e70001ea87346a7925aee06 include/private/xinclude.h
-a14a170c9fc412f09f0fb980b30f18be include/private/xpath.h
-ebdf628f8a0505f16f2e545895e3e7d1 include/private/xzlib.h
-e857d2ed47c0848d6f469ebc16ef31f1 include/wsockcompat.h
-fd5acf7865455100e3a497f9d4d1d58c legacy.c
-c2b5c54ee40fd7bfba8eb6b9e90d6dbd libxml.h
-67985a9e0fc42eebc29d12b884baa00a list.c
-a9e486124ef2c3a00ecb44001d774484 nanoftp.c
-a2c34ca6d295906ebc9b56d8e056bf7a nanohttp.c
-ee9f8b57c3ed99928380467f80d7df11 parser.c
-5d98a417da5fd6a7f614b6a877c246a9 parserInternals.c
-8809dafc22e8463d81a392ac8a853a59 pattern.c
-15a40570e75a1cf9f9da7350f9557b86 relaxng.c
-b66e180243852be9fa9f97b0722679ba runsuite.c
-aec7e53688c694f559010cb2a46f30be runtest.c
-feb122dee4d10cb493ca85bbb2162792 runxmlconf.c
-fc8947f2849d2f27a30318dc3ca831f5 schematron.c
-c48cacc169fbe69e961ceafbfb92ee71 testModule.c
-673cbe4047f34b7d954fd597d46b8716 testThreads.c
-e85d38ab99ab20ed6649989919e52fbd testapi.c
-d665963cfccaa91533d3dfb9f69da42a testchar.c
-2792f948169570feeb744ddf0cce5025 testdict.c
-6a3e7cbf9864c04639a1a8ac0c388ea2 testdso.c
-e84fe8d1a9d8ea089bf9ea8544a6ea1b testlimits.c
-c3b4626e621b6abe586944ec0e79351e testparser.c
-f9dd10b6caf75faf002e92b703b36897 testrecurse.c
-bef5d0bbecbb90f5a441e52bd2f926a2 threads.c
-1bcb15667ab695cdd2cc8d5b1bc05169 timsort.h
-9abdf46cb6883de83f7bc2e9fbbf717a tree.c
-5b543ee91a3c2f2c4fb79e37caa071ea trio.c
-8b21aea67b16387f2f61a9f36717cdb9 trio.h
-a1e52d4d4c9bcba53027aa2fd65c4eef triodef.h
-5a8e54865b5685e0863810556180ef98 trionan.c
-0c9b238876ae233fd259092313287d58 trionan.h
-e79fa3e246145ff28ae6ee96c797b78c triop.h
-ae2f0b85a98ac525c8a215e509ac63b1 triostr.c
-b93afcad9107d48ce7e66b84db7159c7 triostr.h
-eac8b302c12669b0ec1b15afd912dcdf uri.c
-fd3d55b1d9817a9ef205f35b1d60f527 valid.c
-8ab2045fb3bb5553449a93c85ebbb58a win32/config.h
-9ca0965eeabe09b4f8d9a1c6c5d8c3b0 win32/libxml2.rc
-27b6a7946ac148c1f96755bf442ef0f4 xinclude.c
-0a034450d155e35ec8ba99ee2005b695 xlink.c
-ec9a5e17f4cb2e520e10f5a2d6fc71fc xmlIO.c
-28bb81f9966d3ec48c510dd56fa10b94 xmlcatalog.c
-19ebfd8c205fae4022bb30d387831a36 xmllint.c
-47188d0524f25fdb396703aa6d5e1fd6 xmlmemory.c
-096b464ed7bd0decd5a9a6d209f0fabd xmlmodule.c
-6e71ac671a381c09cbc398e47e5ba33a xmlreader.c
-976c32247397c82331e8621977613ea4 xmlregexp.c
-419d628dc26e76442a30f4797c770a80 xmlsave.c
-c6a6f950f16ba8d1e15ae0d384b259ca xmlschemas.c
-906205b67f1d974598edee0322e3c234 xmlschemastypes.c
-7b87ec18a05dfab6a30e1c3667d7edee xmlstring.c
-c9097be7e143f99684f19d937a775144 xmlunicode.c
-110e6d33af683f1b6b04bb53bfe6bb27 xmlwriter.c
-4811ad2391b3697581d9045a9ad0fcfb xpath.c
-2f6ca95b7ee6583b611f2f2b7e566579 xpointer.c
-4f1552a87445e82f1c918eabd97479f1 xzlib.c
diff --git a/distfiles/libxml2-2.12.8.tar.xz b/distfiles/libxml2-2.12.8.tar.xz
deleted file mode 100644
index 586f0d2..0000000
Binary files a/distfiles/libxml2-2.12.8.tar.xz and /dev/null differ
diff --git a/distfiles/libxml2-2.12.8-import.lst b/distfiles/libxml2-2.13.0-import.lst
similarity index 96%
rename from distfiles/libxml2-2.12.8-import.lst
rename to distfiles/libxml2-2.13.0-import.lst
index 1edb306..1e114aa 100644
--- a/distfiles/libxml2-2.12.8-import.lst
+++ b/distfiles/libxml2-2.13.0-import.lst
@@ -106,14 +106,6 @@ testrecurse.c
threads.c
timsort.h
tree.c
-trio.c
-trio.h
-triodef.h
-trionan.c
-trionan.h
-triop.h
-triostr.c
-triostr.h
uri.c
valid.c
win32/config.h
diff --git a/distfiles/libxml2-2.13.0-import.md5 b/distfiles/libxml2-2.13.0-import.md5
new file mode 100644
index 0000000..44dea8b
--- /dev/null
+++ b/distfiles/libxml2-2.13.0-import.md5
@@ -0,0 +1,130 @@
+f437ed9058e8e5135e47c01e973376ba Copyright
+16f41a2c516aa0db1295fd935164345c HTMLparser.c
+d04a2b2879cb84c5c3a195c2d444b335 HTMLtree.c
+dd63184811cb2ff705c3e466364d3773 INSTALL
+516fcfeaa16a8f29342699b27202859d NEWS
+5f32c16a4eccf442197b65fa65f3c7b8 README.libxml2.md
+7283878f36a935a3c00df077cf45af54 SAX.c
+4bb688a8949366334e6803484a0db05b SAX2.c
+67a65054d57590e61fdb1e70d2ea5a96 buf.c
+4b44ee7f5a69c1058b5e78cecd37a15c c14n.c
+b86dee5a15a23fcae795b2fb2544b8dc catalog.c
+691708e81dee605336b6ef6e431c5c21 chvalid.c
+697a63537714f6d73508f642b8caf24b debugXML.c
+08d37f8cc00ce8576a00dd2c2725ffe3 dict.c
+c9a558a311456f1df0ce4da7fec493ca encoding.c
+74aea6c1f67db19f14a4ea658caabb50 entities.c
+1614814772ec00261f6c68dbb3fb2e87 error.c
+4a0ab9ada11a64828012376799576cfa globals.c
+d8e4da290e7f5ca784452d2ba5f65789 hash.c
+c0e828b83cec6c6c1e8ebd53a8ce1de4 include/libxml/HTMLparser.h
+bb4e2df91d33306ab3c2d71374559877 include/libxml/HTMLtree.h
+44e6202b2e65e38c48a5cacb75afe5bf include/libxml/SAX.h
+2f6eb29ddd29a6380634e0ba4757f102 include/libxml/SAX2.h
+eeca649010f9bdc2a60b069766e030ab include/libxml/c14n.h
+17bea9cec4f3b2fb59a68af652c27ad8 include/libxml/catalog.h
+5b94bc432b4ab477a11761182334b646 include/libxml/chvalid.h
+63619fe1dbd8ae82c1040d7df0c7eb6e include/libxml/debugXML.h
+d00de0e505d1b4dfcccf9ff38837b61a include/libxml/dict.h
+8d3a048f503607ca9fbdc63bfa27d02e include/libxml/encoding.h
+8821188af2534b982d91cb73cf9a4c96 include/libxml/entities.h
+bc51344e21f8d3b7f0fc93cc9d554243 include/libxml/globals.h
+637596e31cab013c73d81e02a31a5b65 include/libxml/hash.h
+90371c7017be1221a0c4d20089ade92a include/libxml/list.h
+d5c907a6d7d205e286168e007f32504c include/libxml/nanoftp.h
+95b1e4eadd008ebd16424f0f47213062 include/libxml/nanohttp.h
+d863425ee6d4ffe90f7af8532d194095 include/libxml/parser.h
+b0d1746c566f0a4e1c368d6b1f734564 include/libxml/parserInternals.h
+dfa0e955ce14744df32c8a050c5ee84a include/libxml/pattern.h
+d752e41ee40c2b028d0adb34ffc38810 include/libxml/relaxng.h
+853377a2dbf74e9b0d679dcfcc1859b9 include/libxml/schemasInternals.h
+7a163ee849171ffc2471a89704a33643 include/libxml/schematron.h
+84310bd67922e532329432f7ab04338c include/libxml/threads.h
+ab717587b70618c1482aaead02514ff5 include/libxml/tree.h
+d08bbbc90b3d1d31309fd93c9681390f include/libxml/uri.h
+6dc6a9c1e7a9c651d38e34f6b336c2fc include/libxml/valid.h
+cf36fb20efcb8e5ad770e1d7ac858910 include/libxml/xinclude.h
+4c7ff0fcbc3595d38f47e41f703dbc61 include/libxml/xlink.h
+0971aca35e60af238343eb745771c0d5 include/libxml/xmlIO.h
+78602d66c5db00b0deece2c56ab86d43 include/libxml/xmlautomata.h
+04fa9aa45df384fe962db1a14fb59553 include/libxml/xmlerror.h
+225d59fc76e039255b1c6aa3f15771b7 include/libxml/xmlexports.h
+13b117b714ad87f0fb17d302d9580cf3 include/libxml/xmlmemory.h
+1dda0f8301c72cab8c0015a4f36d008f include/libxml/xmlmodule.h
+288e26a1a1b1e495a463ff90b7d243d7 include/libxml/xmlreader.h
+5f98d803fb4dd3fda837e2f922ce4e6a include/libxml/xmlregexp.h
+f48903903819d60b25e6faf03c8161e3 include/libxml/xmlsave.h
+f4c5548787cac73cd7c6d18a07555393 include/libxml/xmlschemas.h
+ac3b6d0c4a6fc4ea9fea5652b46b2992 include/libxml/xmlschemastypes.h
+74cf81ae5e6c6b553e49683528d78b6b include/libxml/xmlstring.h
+157b92f46696fd22d89f7250de7e30ec include/libxml/xmlunicode.h
+237a31e0b6328115ed5c1673138615e6 include/libxml/xmlwriter.h
+3bbf2dc32947c6f1a6f7cd0da788d86a include/libxml/xpath.h
+348e82b05d463eca3d661e2cc2db9aee include/libxml/xpathInternals.h
+74590f782d9b322ce115d1530e6f74d6 include/libxml/xpointer.h
+238e603990de2fbc5f05e46331be9cb4 include/private/buf.h
+1dc45f80ded4ff83027aed7c84091d9d include/private/dict.h
+ef188f33103bfaa4728d4d2fb885f67a include/private/enc.h
+2c7f255c7af500c08d19cfb53087a4f4 include/private/entities.h
+bef80badd674ff57e922a7ab5774674b include/private/error.h
+d2eb48f52daec99534d38aef2bdbf201 include/private/globals.h
+75db2838e28a9521292c484ccbb63fed include/private/html.h
+d6f456de62fd2c94214ebbaab1ea3f7c include/private/io.h
+365385352b21fd09182380def0b8b7b5 include/private/memory.h
+0db2d8833876738d1a065fbef3231ed5 include/private/parser.h
+11c849f3c342b0587c20ac44037e0efa include/private/regexp.h
+ba3898fbcbfb81535dbb16c7fdeaaaf7 include/private/save.h
+f80f9d5ff71ecd8a4763478227748544 include/private/string.h
+a4976b987498c427b83793894d46fbed include/private/threads.h
+80d8cfec33f517cb7fe9753c7d7d5c52 include/private/tree.h
+aa8f6d446e70001ea87346a7925aee06 include/private/xinclude.h
+fbf5b733beada0f7a1eb01c2df5a0b78 include/private/xpath.h
+78ce4d27f7df28823e8d7ab368d123a6 include/private/xzlib.h
+e857d2ed47c0848d6f469ebc16ef31f1 include/wsockcompat.h
+cdbcf52ea11b6ee99454e3b9a3adeaac legacy.c
+9a9c078482f505d50c1235f918d334bd libxml.h
+62f33a8621e3442770fd15a540a7eba0 list.c
+040942573dbd47e7188991ab3c9c9a99 nanoftp.c
+4c676ca8672af9c242eab69fb9e2056f nanohttp.c
+cae11ea48cd0e72f5ce5b6fbc4c6636c parser.c
+3c13537789e87f0a1c8a6a54a943fa84 parserInternals.c
+fc88d174a7b70de62c609c32ce3f55f8 pattern.c
+06b7f056c759cff032979e0075c5b318 relaxng.c
+371edae07b81c37668065294e77dedcd runsuite.c
+7812bd8b322311a772526b9904ab18ed runtest.c
+8fa00f5991a396805fac801084d67aca runxmlconf.c
+ed005321a17c5795e51e10c384c1f5d9 schematron.c
+c48cacc169fbe69e961ceafbfb92ee71 testModule.c
+673cbe4047f34b7d954fd597d46b8716 testThreads.c
+37a4c872a13c70c1e13022f12d21614b testapi.c
+5a234e72bb26f3f42c86c630cef998f3 testchar.c
+8efef0b6535d6c069678e9f6750d3742 testdict.c
+6a3e7cbf9864c04639a1a8ac0c388ea2 testdso.c
+e7f8098f4a9e147624c3cf7d652a70c0 testlimits.c
+ac0599e08f02704f5d7db1e36134248f testparser.c
+71ea68a83739869caba574c1725fba96 testrecurse.c
+d746403de87ca28dbb43a4a76e63a3d6 threads.c
+1bcb15667ab695cdd2cc8d5b1bc05169 timsort.h
+f4cb2dec0f55e6bd9c20dbd1ae562759 tree.c
+7be25cd62649ec06302c67a0dbdcccc7 uri.c
+e1828d328a36cd0eea27256123122946 valid.c
+8ab2045fb3bb5553449a93c85ebbb58a win32/config.h
+9ca0965eeabe09b4f8d9a1c6c5d8c3b0 win32/libxml2.rc
+9e1d1292d776b102e1ad735144d52e48 xinclude.c
+0a034450d155e35ec8ba99ee2005b695 xlink.c
+e98f05954ecf94bbbf9438b995ff30bd xmlIO.c
+28bb81f9966d3ec48c510dd56fa10b94 xmlcatalog.c
+7eeb0736114d53f08e4be4d611e579dd xmllint.c
+9a191c58eb3f035c795898caea8e689b xmlmemory.c
+9d8d0df11b80a714e97da726359977dc xmlmodule.c
+0e186abcab75a69ea5c5b144834a88b6 xmlreader.c
+fda6796d6766ba055664f2993eca5ed7 xmlregexp.c
+35a26cd93568987405da54e9279d1359 xmlsave.c
+7ad15c4a469cee12b90af8115dd76b5e xmlschemas.c
+991c4949ca7a25c99a7beff8e7516915 xmlschemastypes.c
+82c2b7394f560d8af467b779026d3972 xmlstring.c
+c9097be7e143f99684f19d937a775144 xmlunicode.c
+a8ab2ac1eb6a00dccdae814c1cfcea68 xmlwriter.c
+640161b959d6c0b89b5ca3c57e841436 xpath.c
+dcf0c2434204059b5d6f03346dec1004 xpointer.c
+8798ea780f20ac559991cf1710c29087 xzlib.c
diff --git a/distfiles/libxml2-2.13.0.tar.xz b/distfiles/libxml2-2.13.0.tar.xz
new file mode 100644
index 0000000..4fa0fab
Binary files /dev/null and b/distfiles/libxml2-2.13.0.tar.xz differ
diff --git a/encoding.c b/encoding.c
index bc2772d..04c24e4 100644
--- a/encoding.c
+++ b/encoding.c
@@ -71,57 +71,6 @@ static int xmlCharEncodingAliasesMax = 0;
static int xmlLittleEndian = 1;
-#ifdef LIBXML_ICU_ENABLED
-static uconv_t*
-openIcuConverter(const char* name, int toUnicode)
-{
- UErrorCode status = U_ZERO_ERROR;
- uconv_t *conv = (uconv_t *) xmlMalloc(sizeof(uconv_t));
- if (conv == NULL)
- return NULL;
-
- conv->pivot_source = conv->pivot_buf;
- conv->pivot_target = conv->pivot_buf;
-
- conv->uconv = ucnv_open(name, &status);
- if (U_FAILURE(status))
- goto error;
-
- status = U_ZERO_ERROR;
- if (toUnicode) {
- ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP,
- NULL, NULL, NULL, &status);
- }
- else {
- ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP,
- NULL, NULL, NULL, &status);
- }
- if (U_FAILURE(status))
- goto error;
-
- status = U_ZERO_ERROR;
- conv->utf8 = ucnv_open("UTF-8", &status);
- if (U_SUCCESS(status))
- return conv;
-
-error:
- if (conv->uconv)
- ucnv_close(conv->uconv);
- xmlFree(conv);
- return NULL;
-}
-
-static void
-closeIcuConverter(uconv_t *conv)
-{
- if (conv != NULL) {
- ucnv_close(conv->uconv);
- ucnv_close(conv->utf8);
- xmlFree(conv);
- }
-}
-#endif /* LIBXML_ICU_ENABLED */
-
/************************************************************************
* *
* Conversions To/From UTF8 encoding *
@@ -1374,6 +1323,8 @@ static const xmlCharEncodingHandler defaultHandlers[] = {
static const xmlCharEncodingHandler *xmlUTF16LEHandler = &defaultHandlers[1];
static const xmlCharEncodingHandler *xmlUTF16BEHandler = &defaultHandlers[2];
+static const xmlCharEncodingHandler *xmlLatin1Handler = &defaultHandlers[4];
+static const xmlCharEncodingHandler *xmlAsciiHandler = &defaultHandlers[5];
/* the size should be growable, but it's not a big deal ... */
#define MAX_ENCODING_HANDLERS 50
@@ -1535,162 +1486,460 @@ xmlRegisterCharEncodingHandler(xmlCharEncodingHandlerPtr handler) {
}
}
+#ifdef LIBXML_ICONV_ENABLED
+static int
+xmlCreateIconvHandler(const char *name, xmlCharEncodingHandler **out) {
+ xmlCharEncodingHandlerPtr enc = NULL;
+ iconv_t icv_in = (iconv_t) -1;
+ iconv_t icv_out = (iconv_t) -1;
+ int ret;
+
+ *out = NULL;
+
+ icv_in = iconv_open("UTF-8", name);
+ if (icv_in == (iconv_t) -1) {
+ if (errno == EINVAL)
+ ret = XML_ERR_UNSUPPORTED_ENCODING;
+ else if (errno == ENOMEM)
+ ret = XML_ERR_NO_MEMORY;
+ else
+ ret = XML_ERR_SYSTEM;
+ goto error;
+ }
+
+ icv_out = iconv_open(name, "UTF-8");
+ if (icv_out == (iconv_t) -1) {
+ if (errno == EINVAL)
+ ret = XML_ERR_UNSUPPORTED_ENCODING;
+ else if (errno == ENOMEM)
+ ret = XML_ERR_NO_MEMORY;
+ else
+ ret = XML_ERR_SYSTEM;
+ goto error;
+ }
+
+ enc = xmlMalloc(sizeof(*enc));
+ if (enc == NULL) {
+ ret = XML_ERR_NO_MEMORY;
+ goto error;
+ }
+ memset(enc, 0, sizeof(*enc));
+
+ enc->name = xmlMemStrdup(name);
+ if (enc->name == NULL) {
+ ret = XML_ERR_NO_MEMORY;
+ goto error;
+ }
+ enc->iconv_in = icv_in;
+ enc->iconv_out = icv_out;
+
+ *out = enc;
+ return(0);
+
+error:
+ if (enc != NULL)
+ xmlFree(enc);
+ if (icv_in != (iconv_t) -1)
+ iconv_close(icv_in);
+ if (icv_out != (iconv_t) -1)
+ iconv_close(icv_out);
+ return(ret);
+}
+#endif /* LIBXML_ICONV_ENABLED */
+
+#ifdef LIBXML_ICU_ENABLED
+static int
+openIcuConverter(const char* name, int toUnicode, uconv_t **out)
+{
+ UErrorCode status;
+ uconv_t *conv;
+
+ *out = NULL;
+
+ conv = (uconv_t *) xmlMalloc(sizeof(uconv_t));
+ if (conv == NULL)
+ return(XML_ERR_NO_MEMORY);
+
+ conv->pivot_source = conv->pivot_buf;
+ conv->pivot_target = conv->pivot_buf;
+
+ status = U_ZERO_ERROR;
+ conv->uconv = ucnv_open(name, &status);
+ if (U_FAILURE(status))
+ goto error;
+
+ status = U_ZERO_ERROR;
+ if (toUnicode) {
+ ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP,
+ NULL, NULL, NULL, &status);
+ }
+ else {
+ ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP,
+ NULL, NULL, NULL, &status);
+ }
+ if (U_FAILURE(status))
+ goto error;
+
+ status = U_ZERO_ERROR;
+ conv->utf8 = ucnv_open("UTF-8", &status);
+ if (U_FAILURE(status))
+ goto error;
+
+ *out = conv;
+ return(0);
+
+error:
+ if (conv->uconv)
+ ucnv_close(conv->uconv);
+ xmlFree(conv);
+
+ if (status == U_FILE_ACCESS_ERROR)
+ return(XML_ERR_UNSUPPORTED_ENCODING);
+ if (status == U_MEMORY_ALLOCATION_ERROR)
+ return(XML_ERR_NO_MEMORY);
+ return(XML_ERR_SYSTEM);
+}
+
+static void
+closeIcuConverter(uconv_t *conv)
+{
+ if (conv == NULL)
+ return;
+ ucnv_close(conv->uconv);
+ ucnv_close(conv->utf8);
+ xmlFree(conv);
+}
+
+static int
+xmlCreateUconvHandler(const char *name, xmlCharEncodingHandler **out) {
+ xmlCharEncodingHandlerPtr enc = NULL;
+ uconv_t *ucv_in = NULL;
+ uconv_t *ucv_out = NULL;
+ int ret;
+
+ ret = openIcuConverter(name, 1, &ucv_in);
+ if (ret != 0)
+ goto error;
+ ret = openIcuConverter(name, 0, &ucv_out);
+ if (ret != 0)
+ goto error;
+
+ enc = (xmlCharEncodingHandlerPtr)
+ xmlMalloc(sizeof(xmlCharEncodingHandler));
+ if (enc == NULL) {
+ ret = XML_ERR_NO_MEMORY;
+ goto error;
+ }
+ memset(enc, 0, sizeof(xmlCharEncodingHandler));
+
+ enc->name = xmlMemStrdup(name);
+ if (enc->name == NULL) {
+ ret = XML_ERR_NO_MEMORY;
+ goto error;
+ }
+ enc->input = NULL;
+ enc->output = NULL;
+ enc->uconv_in = ucv_in;
+ enc->uconv_out = ucv_out;
+
+ *out = enc;
+ return(0);
+
+error:
+ if (enc != NULL)
+ xmlFree(enc);
+ if (ucv_in != NULL)
+ closeIcuConverter(ucv_in);
+ if (ucv_out != NULL)
+ closeIcuConverter(ucv_out);
+ return(ret);
+}
+#endif /* LIBXML_ICU_ENABLED */
+
/**
- * xmlGetCharEncodingHandler:
+ * xmlFindExtraHandler:
+ * @name: a string describing the char encoding.
+ * @output: boolean, use handler for output
+ * @out: pointer to resulting handler
+ *
+ * Search the non-default handlers for an exact match.
+ *
+ * Returns 0 on success, 1 if no handler was found, -1 if a memory
+ * allocation failed.
+ */
+static int
+xmlFindExtraHandler(const char *name, int output,
+ xmlCharEncodingHandler **out) {
+ int ret;
+ int i;
+
+ (void) ret;
+
+ if (handlers != NULL) {
+ for (i = 0; i < nbCharEncodingHandler; i++) {
+ xmlCharEncodingHandler *handler = handlers[i];
+
+ if (!xmlStrcasecmp((const xmlChar *) name,
+ (const xmlChar *) handler->name)) {
+ if (output) {
+ if (handler->output != NULL) {
+ *out = handler;
+ return(0);
+ }
+ } else {
+ if (handler->input != NULL) {
+ *out = handler;
+ return(0);
+ }
+ }
+ }
+ }
+ }
+
+#ifdef LIBXML_ICONV_ENABLED
+ ret = xmlCreateIconvHandler(name, out);
+ if (*out != NULL)
+ return(0);
+ if (ret != XML_ERR_UNSUPPORTED_ENCODING)
+ return(ret);
+#endif /* LIBXML_ICONV_ENABLED */
+
+#ifdef LIBXML_ICU_ENABLED
+ ret = xmlCreateUconvHandler(name, out);
+ if (*out != NULL)
+ return(0);
+ if (ret != XML_ERR_UNSUPPORTED_ENCODING)
+ return(ret);
+#endif /* LIBXML_ICU_ENABLED */
+
+ return(XML_ERR_UNSUPPORTED_ENCODING);
+}
+
+/**
+ * xmlFindHandler:
+ * @name: a string describing the char encoding.
+ * @output: boolean, use handler for output
+ * @out: pointer to resulting handler
+ *
+ * Search all handlers for an exact match.
+ *
+ * Returns 0 on success, 1 if no handler was found, -1 if a memory
+ * allocation failed.
+ */
+static int
+xmlFindHandler(const char *name, int output, xmlCharEncodingHandler **out) {
+ int i;
+
+ /*
+ * Check for default handlers
+ */
+ for (i = 0; i < (int) NUM_DEFAULT_HANDLERS; i++) {
+ xmlCharEncodingHandler *handler;
+
+ handler = (xmlCharEncodingHandler *) &defaultHandlers[i];
+
+ if (xmlStrcasecmp((const xmlChar *) name,
+ (const xmlChar *) handler->name) == 0) {
+ if (output) {
+ if (handler->output != NULL) {
+ *out = handler;
+ return(0);
+ }
+ } else {
+ if (handler->input != NULL) {
+ *out = handler;
+ return(0);
+ }
+ }
+ }
+ }
+
+ /*
+ * Check for other handlers
+ */
+ return(xmlFindExtraHandler(name, output, out));
+}
+
+/**
+ * xmlLookupCharEncodingHandler:
* @enc: an xmlCharEncoding value.
+ * @out: pointer to result
+ *
+ * Find or create a handler matching the encoding. If no default or
+ * registered handler could be found, try to create a handler using
+ * iconv or ICU if supported.
*
- * Search in the registered set the handler able to read/write that encoding.
+ * The handler must be closed with xmlCharEncCloseFunc.
*
- * Returns the handler or NULL if not found
+ * Available since 2.13.0.
+ *
+ * Returns an xmlParserErrors error code.
*/
-xmlCharEncodingHandlerPtr
-xmlGetCharEncodingHandler(xmlCharEncoding enc) {
- xmlCharEncodingHandlerPtr handler;
+int
+xmlLookupCharEncodingHandler(xmlCharEncoding enc,
+ xmlCharEncodingHandler **out) {
+ const char *name = NULL;
+ static const char *const ebcdicNames[] = {
+ "EBCDIC", "ebcdic", "EBCDIC-US", "IBM-037"
+ };
+ static const char *const ucs4Names[] = {
+ "ISO-10646-UCS-4", "UCS-4", "UCS4"
+ };
+ static const char *const ucs2Names[] = {
+ "ISO-10646-UCS-2", "UCS-2", "UCS2"
+ };
+ static const char *const shiftJisNames[] = {
+ "SHIFT-JIS", "SHIFT_JIS", "Shift_JIS",
+ };
+ const char *const *names = NULL;
+ int numNames = 0;
+ int ret;
+ int i;
+
+ if (out == NULL)
+ return(XML_ERR_ARGUMENT);
+ *out = NULL;
switch (enc) {
case XML_CHAR_ENCODING_ERROR:
- return(NULL);
+ return(XML_ERR_UNSUPPORTED_ENCODING);
case XML_CHAR_ENCODING_NONE:
- return(NULL);
+ return(0);
case XML_CHAR_ENCODING_UTF8:
- return(NULL);
+ return(0);
case XML_CHAR_ENCODING_UTF16LE:
- return((xmlCharEncodingHandlerPtr) xmlUTF16LEHandler);
+ *out = (xmlCharEncodingHandler *) xmlUTF16LEHandler;
+ return(0);
case XML_CHAR_ENCODING_UTF16BE:
- return((xmlCharEncodingHandlerPtr) xmlUTF16BEHandler);
+ *out = (xmlCharEncodingHandler *) xmlUTF16BEHandler;
+ return(0);
case XML_CHAR_ENCODING_EBCDIC:
- handler = xmlFindCharEncodingHandler("EBCDIC");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("ebcdic");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("EBCDIC-US");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("IBM-037");
- if (handler != NULL) return(handler);
+ names = ebcdicNames;
+ numNames = sizeof(ebcdicNames) / sizeof(ebcdicNames[0]);
break;
case XML_CHAR_ENCODING_UCS4BE:
- handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS-4");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS4");
- if (handler != NULL) return(handler);
- break;
case XML_CHAR_ENCODING_UCS4LE:
- handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS-4");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS4");
- if (handler != NULL) return(handler);
+ names = ucs4Names;
+ numNames = sizeof(ucs4Names) / sizeof(ucs4Names[0]);
break;
case XML_CHAR_ENCODING_UCS4_2143:
break;
case XML_CHAR_ENCODING_UCS4_3412:
break;
case XML_CHAR_ENCODING_UCS2:
- handler = xmlFindCharEncodingHandler("ISO-10646-UCS-2");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS-2");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS2");
- if (handler != NULL) return(handler);
+ names = ucs2Names;
+ numNames = sizeof(ucs2Names) / sizeof(ucs2Names[0]);
break;
- /*
- * We used to keep ISO Latin encodings native in the
- * generated data. This led to so many problems that
- * this has been removed. One can still change this
- * back by registering no-ops encoders for those
- */
+ case XML_CHAR_ENCODING_ASCII:
+ *out = (xmlCharEncodingHandler *) xmlAsciiHandler;
+ return(0);
case XML_CHAR_ENCODING_8859_1:
- handler = xmlFindCharEncodingHandler("ISO-8859-1");
- if (handler != NULL) return(handler);
- break;
+ *out = (xmlCharEncodingHandler *) xmlLatin1Handler;
+ return(0);
case XML_CHAR_ENCODING_8859_2:
- handler = xmlFindCharEncodingHandler("ISO-8859-2");
- if (handler != NULL) return(handler);
+ name = "ISO-8859-2";
break;
case XML_CHAR_ENCODING_8859_3:
- handler = xmlFindCharEncodingHandler("ISO-8859-3");
- if (handler != NULL) return(handler);
+ name = "ISO-8859-3";
break;
case XML_CHAR_ENCODING_8859_4:
- handler = xmlFindCharEncodingHandler("ISO-8859-4");
- if (handler != NULL) return(handler);
+ name = "ISO-8859-4";
break;
case XML_CHAR_ENCODING_8859_5:
- handler = xmlFindCharEncodingHandler("ISO-8859-5");
- if (handler != NULL) return(handler);
+ name = "ISO-8859-5";
break;
case XML_CHAR_ENCODING_8859_6:
- handler = xmlFindCharEncodingHandler("ISO-8859-6");
- if (handler != NULL) return(handler);
+ name = "ISO-8859-6";
break;
case XML_CHAR_ENCODING_8859_7:
- handler = xmlFindCharEncodingHandler("ISO-8859-7");
- if (handler != NULL) return(handler);
+ name = "ISO-8859-7";
break;
case XML_CHAR_ENCODING_8859_8:
- handler = xmlFindCharEncodingHandler("ISO-8859-8");
- if (handler != NULL) return(handler);
+ name = "ISO-8859-8";
break;
case XML_CHAR_ENCODING_8859_9:
- handler = xmlFindCharEncodingHandler("ISO-8859-9");
- if (handler != NULL) return(handler);
+ name = "ISO-8859-9";
break;
-
case XML_CHAR_ENCODING_2022_JP:
- handler = xmlFindCharEncodingHandler("ISO-2022-JP");
- if (handler != NULL) return(handler);
+ name = "ISO-2022-JP";
break;
case XML_CHAR_ENCODING_SHIFT_JIS:
- handler = xmlFindCharEncodingHandler("SHIFT-JIS");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("SHIFT_JIS");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("Shift_JIS");
- if (handler != NULL) return(handler);
+ names = shiftJisNames;
+ numNames = sizeof(shiftJisNames) / sizeof(shiftJisNames[0]);
break;
case XML_CHAR_ENCODING_EUC_JP:
- handler = xmlFindCharEncodingHandler("EUC-JP");
- if (handler != NULL) return(handler);
+ name = "EUC-JP";
break;
default:
break;
}
- return(NULL);
+ if (name != NULL)
+ return(xmlFindExtraHandler(name, 0, out));
+
+ if (names != NULL) {
+ for (i = 0; i < numNames; i++) {
+ ret = xmlFindExtraHandler(names[i], 0, out);
+ if (*out != NULL)
+ return(0);
+ if (ret != XML_ERR_UNSUPPORTED_ENCODING)
+ return(ret);
+ }
+ }
+
+ return(XML_ERR_UNSUPPORTED_ENCODING);
}
/**
- * xmlFindCharEncodingHandler:
- * @name: a string describing the char encoding.
+ * xmlGetCharEncodingHandler:
+ * @enc: an xmlCharEncoding value.
*
- * Search in the registered set the handler able to read/write that encoding
- * or create a new one.
+ * DEPRECATED: Use xmlLookupCharEncodingHandler which has better error
+ * reporting.
*
- * Returns the handler or NULL if not found
+ * Returns the handler or NULL if no handler was found or an error
+ * occurred.
*/
xmlCharEncodingHandlerPtr
-xmlFindCharEncodingHandler(const char *name) {
+xmlGetCharEncodingHandler(xmlCharEncoding enc) {
+ xmlCharEncodingHandler *ret;
+
+ xmlLookupCharEncodingHandler(enc, &ret);
+ return(ret);
+}
+
+/**
+ * xmlOpenCharEncodingHandler:
+ * @name: a string describing the char encoding.
+ * @output: boolean, use handler for output
+ * @out: pointer to result
+ *
+ * Find or create a handler matching the encoding. If no default or
+ * registered handler could be found, try to create a handler using
+ * iconv or ICU if supported.
+ *
+ * The handler must be closed with xmlCharEncCloseFunc.
+ *
+ * Available since 2.13.0.
+ *
+ * Returns an xmlParserErrors error code.
+ */
+int
+xmlOpenCharEncodingHandler(const char *name, int output,
+ xmlCharEncodingHandler **out) {
const char *nalias;
const char *norig;
- xmlCharEncoding alias;
-#ifdef LIBXML_ICONV_ENABLED
- xmlCharEncodingHandlerPtr enc;
- iconv_t icv_in, icv_out;
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
- xmlCharEncodingHandlerPtr encu;
- uconv_t *ucv_in, *ucv_out;
-#endif /* LIBXML_ICU_ENABLED */
- char upper[100];
- int i;
+ xmlCharEncoding enc;
+ int ret;
+
+ if (out == NULL)
+ return(XML_ERR_ARGUMENT);
+ *out = NULL;
- if (name == NULL) return(NULL);
- if (name[0] == 0) return(NULL);
+ if (name == NULL)
+ return(XML_ERR_ARGUMENT);
/*
* Do the alias resolution
@@ -1700,111 +1949,35 @@ xmlFindCharEncodingHandler(const char *name) {
if (nalias != NULL)
name = nalias;
- /*
- * Check first for directly registered encoding names
- */
- for (i = 0;i < 99;i++) {
- upper[i] = (char) toupper((unsigned char) name[i]);
- if (upper[i] == 0) break;
- }
- upper[i] = 0;
-
- for (i = 0; i < (int) NUM_DEFAULT_HANDLERS; i++) {
- if (strcmp(upper, defaultHandlers[i].name) == 0)
- return((xmlCharEncodingHandlerPtr) &defaultHandlers[i]);
- }
-
- if (handlers != NULL) {
- for (i = 0;i < nbCharEncodingHandler; i++) {
- if (!strcmp(upper, handlers[i]->name)) {
- return(handlers[i]);
- }
- }
- }
-
-#ifdef LIBXML_ICONV_ENABLED
- /* check whether iconv can handle this */
- icv_in = iconv_open("UTF-8", name);
- icv_out = iconv_open(name, "UTF-8");
- if (icv_in == (iconv_t) -1) {
- icv_in = iconv_open("UTF-8", upper);
- }
- if (icv_out == (iconv_t) -1) {
- icv_out = iconv_open(upper, "UTF-8");
- }
- if ((icv_in != (iconv_t) -1) && (icv_out != (iconv_t) -1)) {
- enc = (xmlCharEncodingHandlerPtr)
- xmlMalloc(sizeof(xmlCharEncodingHandler));
- if (enc == NULL) {
- iconv_close(icv_in);
- iconv_close(icv_out);
- return(NULL);
- }
- memset(enc, 0, sizeof(xmlCharEncodingHandler));
- enc->name = xmlMemStrdup(name);
- if (enc->name == NULL) {
- xmlFree(enc);
- iconv_close(icv_in);
- iconv_close(icv_out);
- return(NULL);
- }
- enc->input = NULL;
- enc->output = NULL;
- enc->iconv_in = icv_in;
- enc->iconv_out = icv_out;
- return enc;
- } else if ((icv_in != (iconv_t) -1) || icv_out != (iconv_t) -1) {
- if (icv_in != (iconv_t) -1)
- iconv_close(icv_in);
- else
- iconv_close(icv_out);
- }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
- /* check whether icu can handle this */
- ucv_in = openIcuConverter(name, 1);
- ucv_out = openIcuConverter(name, 0);
- if (ucv_in != NULL && ucv_out != NULL) {
- encu = (xmlCharEncodingHandlerPtr)
- xmlMalloc(sizeof(xmlCharEncodingHandler));
- if (encu == NULL) {
- closeIcuConverter(ucv_in);
- closeIcuConverter(ucv_out);
- return(NULL);
- }
- memset(encu, 0, sizeof(xmlCharEncodingHandler));
- encu->name = xmlMemStrdup(name);
- if (encu->name == NULL) {
- xmlFree(encu);
- closeIcuConverter(ucv_in);
- closeIcuConverter(ucv_out);
- return(NULL);
- }
- encu->input = NULL;
- encu->output = NULL;
- encu->uconv_in = ucv_in;
- encu->uconv_out = ucv_out;
- return encu;
- } else if (ucv_in != NULL || ucv_out != NULL) {
- closeIcuConverter(ucv_in);
- closeIcuConverter(ucv_out);
- }
-#endif /* LIBXML_ICU_ENABLED */
+ ret = xmlFindHandler(name, output, out);
+ if (*out != NULL)
+ return(0);
+ if (ret != XML_ERR_UNSUPPORTED_ENCODING)
+ return(ret);
/*
* Fallback using the canonical names
*/
- alias = xmlParseCharEncoding(norig);
- if (alias != XML_CHAR_ENCODING_ERROR) {
- const char* canon;
- canon = xmlGetCharEncodingName(alias);
- if ((canon != NULL) && (strcmp(name, canon))) {
- return(xmlFindCharEncodingHandler(canon));
- }
- }
+ enc = xmlParseCharEncoding(norig);
+ return(xmlLookupCharEncodingHandler(enc, out));
+}
- /* If "none of the above", give up */
- return(NULL);
+/**
+ * xmlFindCharEncodingHandler:
+ * @name: a string describing the char encoding.
+ *
+ * DEPRECATED: Use xmlOpenCharEncodingHandler which has better error
+ * reporting.
+ *
+ * Returns the handler or NULL if no handler was found or an error
+ * occurred.
+ */
+xmlCharEncodingHandlerPtr
+xmlFindCharEncodingHandler(const char *name) {
+ xmlCharEncodingHandler *ret;
+
+ xmlOpenCharEncodingHandler(name, 0, &ret);
+ return(ret);
}
/************************************************************************
@@ -2169,7 +2342,8 @@ xmlCharEncInput(xmlParserInputBufferPtr input)
else
input->rawconsumed += c_in;
- if ((c_out == 0) && (ret != 0)) {
+ if (((ret != 0) && (c_out == 0)) ||
+ (ret == XML_ENC_ERR_MEMORY)) {
if (input->error == 0)
input->error = xmlEncConvertError(ret);
return(ret);
@@ -2277,7 +2451,10 @@ xmlCharEncOutput(xmlOutputBufferPtr output, int init)
if (toconv > 64 * 1024)
toconv = 64 * 1024;
if (toconv * 4 >= written) {
- xmlBufGrow(out, toconv * 4);
+ if (xmlBufGrow(out, toconv * 4) < 0) {
+ ret = XML_ENC_ERR_MEMORY;
+ goto error;
+ }
written = xmlBufAvail(out);
}
if (written > 256 * 1024)
@@ -2314,7 +2491,6 @@ xmlCharEncOutput(xmlOutputBufferPtr output, int init)
*/
charrefLen = snprintf((char *) &charref[0], sizeof(charref),
"%d;", cur);
- xmlBufShrink(in, len);
xmlBufGrow(out, charrefLen * 4);
c_out = xmlBufAvail(out);
c_in = charrefLen;
@@ -2325,13 +2501,15 @@ xmlCharEncOutput(xmlOutputBufferPtr output, int init)
goto error;
}
+ xmlBufShrink(in, len);
xmlBufAddLen(out, c_out);
writtentot += c_out;
goto retry;
}
error:
- if ((writtentot <= 0) && (ret != 0)) {
+ if (((writtentot <= 0) && (ret != 0)) ||
+ (ret == XML_ENC_ERR_MEMORY)) {
if (output->error == 0)
output->error = xmlEncConvertError(ret);
return(ret);
@@ -2762,7 +2940,7 @@ ISO8859xToUTF8(unsigned char* out, int *outlen,
* Lookup tables for ISO-8859-2..ISO-8859-16 transcoding *
************************************************************************/
-static unsigned short const xmlunicodetable_ISO8859_2 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_2 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -2811,7 +2989,7 @@ static const unsigned char xmltranscodetable_ISO8859_2 [48 + 6 * 64] = {
"\x00\x00\x00\xf3\xf4\x00\xf6\xf7\x00\x00\xfa\x00\xfc\xfd\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_3 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_3 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -2864,7 +3042,7 @@ static const unsigned char xmltranscodetable_ISO8859_3 [48 + 7 * 64] = {
"\x00\xf1\xf2\xf3\xf4\x00\xf6\xf7\x00\xf9\xfa\xfb\xfc\x00\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_4 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_4 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -2913,7 +3091,7 @@ static const unsigned char xmltranscodetable_ISO8859_4 [48 + 6 * 64] = {
"\x00\x00\x00\x00\xf4\xf5\xf6\xf7\xf8\x00\xfa\xfb\xfc\x00\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_5 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_5 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -2962,7 +3140,7 @@ static const unsigned char xmltranscodetable_ISO8859_5 [48 + 6 * 64] = {
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_6 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_6 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -3007,7 +3185,7 @@ static const unsigned char xmltranscodetable_ISO8859_6 [48 + 5 * 64] = {
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_7 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_7 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -3060,7 +3238,7 @@ static const unsigned char xmltranscodetable_ISO8859_7 [48 + 7 * 64] = {
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_8 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_8 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -3113,7 +3291,7 @@ static const unsigned char xmltranscodetable_ISO8859_8 [48 + 7 * 64] = {
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_9 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_9 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -3158,7 +3336,7 @@ static const unsigned char xmltranscodetable_ISO8859_9 [48 + 5 * 64] = {
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_10 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_10 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -3211,7 +3389,7 @@ static const unsigned char xmltranscodetable_ISO8859_10 [48 + 7 * 64] = {
"\xf0\x00\x00\xf3\xf4\xf5\xf6\x00\xf8\x00\xfa\xfb\xfc\xfd\xfe\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_11 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_11 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -3260,7 +3438,7 @@ static const unsigned char xmltranscodetable_ISO8859_11 [48 + 6 * 64] = {
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_13 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_13 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -3313,7 +3491,7 @@ static const unsigned char xmltranscodetable_ISO8859_13 [48 + 7 * 64] = {
"\x00\x00\x00\x00\x00\x00\xcd\xed\x00\x00\x00\xcf\xef\x00\x00\x00"
};
-static unsigned short const xmlunicodetable_ISO8859_14 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_14 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -3378,7 +3556,7 @@ static const unsigned char xmltranscodetable_ISO8859_14 [48 + 10 * 64] = {
"\x00\xf1\xf2\xf3\xf4\xf5\xf6\x00\xf8\xf9\xfa\xfb\xfc\xfd\x00\xff"
};
-static unsigned short const xmlunicodetable_ISO8859_15 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_15 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -3427,7 +3605,7 @@ static const unsigned char xmltranscodetable_ISO8859_15 [48 + 6 * 64] = {
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
};
-static unsigned short const xmlunicodetable_ISO8859_16 [128] = {
+static const unsigned short xmlunicodetable_ISO8859_16 [128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
diff --git a/entities.c b/entities.c
index aec5144..f7792a8 100644
--- a/entities.c
+++ b/entities.c
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include "private/entities.h"
#include "private/error.h"
@@ -68,50 +69,11 @@ static xmlEntity xmlEntityApos = {
NULL, NULL, NULL, NULL, 0, 0, 0
};
-/**
- * xmlEntitiesErrMemory:
- * @extra: extra information
- *
- * Handle an out of memory condition
- */
-static void
-xmlEntitiesErrMemory(const char *extra)
-{
- __xmlSimpleError(XML_FROM_TREE, XML_ERR_NO_MEMORY, NULL, NULL, extra);
-}
-
-/**
- * xmlEntitiesErr:
- * @code: the error code
- * @msg: the message
- *
- * Raise an error.
- */
-static void LIBXML_ATTR_FORMAT(2,0)
-xmlEntitiesErr(xmlParserErrors code, const char *msg)
-{
- __xmlSimpleError(XML_FROM_TREE, code, NULL, msg, NULL);
-}
-
-/**
- * xmlEntitiesWarn:
- * @code: the error code
- * @msg: the message
- *
- * Raise a warning.
- */
-static void LIBXML_ATTR_FORMAT(2,0)
-xmlEntitiesWarn(xmlParserErrors code, const char *msg, const xmlChar *str1)
-{
- __xmlRaiseError(NULL, NULL, NULL,
- NULL, NULL, XML_FROM_TREE, code,
- XML_ERR_WARNING, NULL, 0,
- (const char *)str1, NULL, NULL, 0, 0,
- msg, (const char *)str1, NULL);
-}
-
/*
- * xmlFreeEntity : clean-up an entity record.
+ * xmlFreeEntity:
+ * @entity: an entity
+ *
+ * Frees the entity.
*/
void
xmlFreeEntity(xmlEntityPtr entity)
@@ -125,7 +87,7 @@ xmlFreeEntity(xmlEntityPtr entity)
dict = entity->doc->dict;
- if ((entity->children) && (entity->owner == 1) &&
+ if ((entity->children) &&
(entity == (xmlEntityPtr) entity->children->parent))
xmlFreeNodeList(entity->children);
if ((entity->name != NULL) &&
@@ -150,37 +112,43 @@ xmlFreeEntity(xmlEntityPtr entity)
* internal routine doing the entity node structures allocations
*/
static xmlEntityPtr
-xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type,
+xmlCreateEntity(xmlDocPtr doc, const xmlChar *name, int type,
const xmlChar *ExternalID, const xmlChar *SystemID,
const xmlChar *content) {
xmlEntityPtr ret;
ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
- if (ret == NULL) {
- xmlEntitiesErrMemory("xmlCreateEntity: malloc failed");
+ if (ret == NULL)
return(NULL);
- }
memset(ret, 0, sizeof(xmlEntity));
+ ret->doc = doc;
ret->type = XML_ENTITY_DECL;
/*
* fill the structure.
*/
ret->etype = (xmlEntityType) type;
- if (dict == NULL) {
+ if ((doc == NULL) || (doc->dict == NULL))
ret->name = xmlStrdup(name);
- if (ExternalID != NULL)
- ret->ExternalID = xmlStrdup(ExternalID);
- if (SystemID != NULL)
- ret->SystemID = xmlStrdup(SystemID);
- } else {
- ret->name = xmlDictLookup(dict, name, -1);
- ret->ExternalID = xmlStrdup(ExternalID);
- ret->SystemID = xmlStrdup(SystemID);
+ else
+ ret->name = xmlDictLookup(doc->dict, name, -1);
+ if (ret->name == NULL)
+ goto error;
+ if (ExternalID != NULL) {
+ ret->ExternalID = xmlStrdup(ExternalID);
+ if (ret->ExternalID == NULL)
+ goto error;
+ }
+ if (SystemID != NULL) {
+ ret->SystemID = xmlStrdup(SystemID);
+ if (ret->SystemID == NULL)
+ goto error;
}
if (content != NULL) {
ret->length = xmlStrlen(content);
ret->content = xmlStrndup(content, ret->length);
+ if (ret->content == NULL)
+ goto error;
} else {
ret->length = 0;
ret->content = NULL;
@@ -188,28 +156,53 @@ xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type,
ret->URI = NULL; /* to be computed by the layer knowing
the defining entity */
ret->orig = NULL;
- ret->owner = 0;
return(ret);
+
+error:
+ xmlFreeEntity(ret);
+ return(NULL);
}
-/*
- * xmlAddEntity : register a new entity for an entities table.
+/**
+ * xmlAddEntity:
+ * @doc: the document
+ * @extSubset: add to the external or internal subset
+ * @name: the entity name
+ * @type: the entity type XML_xxx_yyy_ENTITY
+ * @ExternalID: the entity external ID if available
+ * @SystemID: the entity system ID if available
+ * @content: the entity content
+ * @out: pointer to resulting entity (optional)
+ *
+ * Register a new entity for this document.
+ *
+ * Available since 2.13.0.
+ *
+ * Returns an xmlParserErrors error code.
*/
-static xmlEntityPtr
-xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
+int
+xmlAddEntity(xmlDocPtr doc, int extSubset, const xmlChar *name, int type,
const xmlChar *ExternalID, const xmlChar *SystemID,
- const xmlChar *content) {
+ const xmlChar *content, xmlEntityPtr *out) {
+ xmlDtdPtr dtd;
xmlDictPtr dict = NULL;
xmlEntitiesTablePtr table = NULL;
xmlEntityPtr ret, predef;
+ int res;
- if (name == NULL)
- return(NULL);
+ if (out != NULL)
+ *out = NULL;
+ if ((doc == NULL) || (name == NULL))
+ return(XML_ERR_ARGUMENT);
+ dict = doc->dict;
+
+ if (extSubset)
+ dtd = doc->extSubset;
+ else
+ dtd = doc->intSubset;
if (dtd == NULL)
- return(NULL);
- if (dtd->doc != NULL)
- dict = dtd->doc->dict;
+ return(XML_DTD_NO_DTD);
switch (type) {
case XML_INTERNAL_GENERAL_ENTITY:
@@ -246,41 +239,60 @@ xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
}
}
}
- if (!valid) {
- xmlEntitiesWarn(XML_ERR_ENTITY_PROCESSING,
- "xmlAddEntity: invalid redeclaration of predefined"
- " entity '%s'", name);
- return(NULL);
- }
+ if (!valid)
+ return(XML_ERR_REDECL_PREDEF_ENTITY);
}
- if (dtd->entities == NULL)
+ if (dtd->entities == NULL) {
dtd->entities = xmlHashCreateDict(0, dict);
+ if (dtd->entities == NULL)
+ return(XML_ERR_NO_MEMORY);
+ }
table = dtd->entities;
break;
case XML_INTERNAL_PARAMETER_ENTITY:
case XML_EXTERNAL_PARAMETER_ENTITY:
- if (dtd->pentities == NULL)
+ if (dtd->pentities == NULL) {
dtd->pentities = xmlHashCreateDict(0, dict);
+ if (dtd->pentities == NULL)
+ return(XML_ERR_NO_MEMORY);
+ }
table = dtd->pentities;
break;
- case XML_INTERNAL_PREDEFINED_ENTITY:
- return(NULL);
+ default:
+ return(XML_ERR_ARGUMENT);
}
- if (table == NULL)
- return(NULL);
- ret = xmlCreateEntity(dict, name, type, ExternalID, SystemID, content);
+ ret = xmlCreateEntity(dtd->doc, name, type, ExternalID, SystemID, content);
if (ret == NULL)
- return(NULL);
- ret->doc = dtd->doc;
+ return(XML_ERR_NO_MEMORY);
- if (xmlHashAddEntry(table, name, ret)) {
+ res = xmlHashAdd(table, name, ret);
+ if (res < 0) {
+ xmlFreeEntity(ret);
+ return(XML_ERR_NO_MEMORY);
+ } else if (res == 0) {
/*
* entity was already defined at another level.
*/
xmlFreeEntity(ret);
- return(NULL);
+ return(XML_WAR_ENTITY_REDEFINED);
}
- return(ret);
+
+ /*
+ * Link it to the DTD
+ */
+ ret->parent = dtd;
+ ret->doc = dtd->doc;
+ if (dtd->last == NULL) {
+ dtd->children = dtd->last = (xmlNodePtr) ret;
+ } else {
+ dtd->last->next = (xmlNodePtr) ret;
+ ret->prev = dtd->last;
+ dtd->last = (xmlNodePtr) ret;
+ }
+
+ if (out != NULL)
+ *out = ret;
+ return(0);
}
/**
@@ -337,34 +349,8 @@ xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type,
const xmlChar *ExternalID, const xmlChar *SystemID,
const xmlChar *content) {
xmlEntityPtr ret;
- xmlDtdPtr dtd;
- if (doc == NULL) {
- xmlEntitiesErr(XML_DTD_NO_DOC,
- "xmlAddDtdEntity: document is NULL");
- return(NULL);
- }
- if (doc->extSubset == NULL) {
- xmlEntitiesErr(XML_DTD_NO_DTD,
- "xmlAddDtdEntity: document without external subset");
- return(NULL);
- }
- dtd = doc->extSubset;
- ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
- if (ret == NULL) return(NULL);
-
- /*
- * Link it to the DTD
- */
- ret->parent = dtd;
- ret->doc = dtd->doc;
- if (dtd->last == NULL) {
- dtd->children = dtd->last = (xmlNodePtr) ret;
- } else {
- dtd->last->next = (xmlNodePtr) ret;
- ret->prev = dtd->last;
- dtd->last = (xmlNodePtr) ret;
- }
+ xmlAddEntity(doc, 1, name, type, ExternalID, SystemID, content, &ret);
return(ret);
}
@@ -386,34 +372,8 @@ xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type,
const xmlChar *ExternalID, const xmlChar *SystemID,
const xmlChar *content) {
xmlEntityPtr ret;
- xmlDtdPtr dtd;
-
- if (doc == NULL) {
- xmlEntitiesErr(XML_DTD_NO_DOC,
- "xmlAddDocEntity: document is NULL");
- return(NULL);
- }
- if (doc->intSubset == NULL) {
- xmlEntitiesErr(XML_DTD_NO_DTD,
- "xmlAddDocEntity: document without internal subset");
- return(NULL);
- }
- dtd = doc->intSubset;
- ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
- if (ret == NULL) return(NULL);
- /*
- * Link it to the DTD
- */
- ret->parent = dtd;
- ret->doc = dtd->doc;
- if (dtd->last == NULL) {
- dtd->children = dtd->last = (xmlNodePtr) ret;
- } else {
- dtd->last->next = (xmlNodePtr) ret;
- ret->prev = dtd->last;
- dtd->last = (xmlNodePtr) ret;
- }
+ xmlAddEntity(doc, 0, name, type, ExternalID, SystemID, content, &ret);
return(ret);
}
@@ -438,21 +398,12 @@ xmlEntityPtr
xmlNewEntity(xmlDocPtr doc, const xmlChar *name, int type,
const xmlChar *ExternalID, const xmlChar *SystemID,
const xmlChar *content) {
- xmlEntityPtr ret;
- xmlDictPtr dict;
-
if ((doc != NULL) && (doc->intSubset != NULL)) {
return(xmlAddDocEntity(doc, name, type, ExternalID, SystemID, content));
}
- if (doc != NULL)
- dict = doc->dict;
- else
- dict = NULL;
- ret = xmlCreateEntity(dict, name, type, ExternalID, SystemID, content);
- if (ret == NULL)
+ if (name == NULL)
return(NULL);
- ret->doc = doc;
- return(ret);
+ return(xmlCreateEntity(doc, name, type, ExternalID, SystemID, content));
}
/**
@@ -604,10 +555,8 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) {
*/
buffer_size = 1000;
buffer = (xmlChar *) xmlMalloc(buffer_size);
- if (buffer == NULL) {
- xmlEntitiesErrMemory("xmlEncodeEntities: malloc failed");
+ if (buffer == NULL)
return(NULL);
- }
out = buffer;
while (*cur != '\0') {
@@ -707,53 +656,18 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) {
* cur[3] is 10xxxxxx if cur[0] is 1111xxxx
* cur[0] is not 11111xxx
*/
- char buf[11], *ptr;
- int val = 0, l = 1;
-
- if (((cur[0] & 0xC0) != 0xC0) ||
- ((cur[1] & 0xC0) != 0x80) ||
- (((cur[0] & 0xE0) == 0xE0) && ((cur[2] & 0xC0) != 0x80)) ||
- (((cur[0] & 0xF0) == 0xF0) && ((cur[3] & 0xC0) != 0x80)) ||
- (((cur[0] & 0xF8) == 0xF8))) {
- xmlEntitiesErr(XML_CHECK_NOT_UTF8,
- "xmlEncodeEntities: input not UTF-8");
- snprintf(buf, sizeof(buf), "%d;", *cur);
- buf[sizeof(buf) - 1] = 0;
- ptr = buf;
- while (*ptr != 0) *out++ = *ptr++;
- cur++;
- continue;
- } else if (*cur < 0xE0) {
- val = (cur[0]) & 0x1F;
- val <<= 6;
- val |= (cur[1]) & 0x3F;
- l = 2;
- } else if (*cur < 0xF0) {
- val = (cur[0]) & 0x0F;
- val <<= 6;
- val |= (cur[1]) & 0x3F;
- val <<= 6;
- val |= (cur[2]) & 0x3F;
- l = 3;
- } else if (*cur < 0xF8) {
- val = (cur[0]) & 0x07;
- val <<= 6;
- val |= (cur[1]) & 0x3F;
- val <<= 6;
- val |= (cur[2]) & 0x3F;
- val <<= 6;
- val |= (cur[3]) & 0x3F;
- l = 4;
- }
- if ((l == 1) || (!IS_CHAR(val))) {
- xmlEntitiesErr(XML_ERR_INVALID_CHAR,
- "xmlEncodeEntities: char out of range\n");
- snprintf(buf, sizeof(buf), "%d;", *cur);
- buf[sizeof(buf) - 1] = 0;
- ptr = buf;
- while (*ptr != 0) *out++ = *ptr++;
- cur++;
- continue;
+ char buf[13], *ptr;
+ int val, l;
+
+ l = 4;
+ val = xmlGetUTF8Char(cur, &l);
+ if (val < 0) {
+ val = 0xFFFD;
+ cur++;
+ } else {
+ if (!IS_CHAR(val))
+ val = 0xFFFD;
+ cur += l;
}
/*
* We could do multiple things here. Just save as a char ref
@@ -762,7 +676,6 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) {
buf[sizeof(buf) - 1] = 0;
ptr = buf;
while (*ptr != 0) *out++ = *ptr++;
- cur += l;
continue;
}
} else if (IS_BYTE_CHAR(*cur)) {
@@ -779,7 +692,6 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) {
return(buffer);
mem_error:
- xmlEntitiesErrMemory("xmlEncodeEntities: realloc failed");
xmlFree(buffer);
return(NULL);
}
@@ -840,10 +752,8 @@ xmlEncodeSpecialChars(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlChar *input)
*/
buffer_size = 1000;
buffer = (xmlChar *) xmlMalloc(buffer_size);
- if (buffer == NULL) {
- xmlEntitiesErrMemory("xmlEncodeSpecialChars: malloc failed");
+ if (buffer == NULL)
return(NULL);
- }
out = buffer;
while (*cur != '\0') {
@@ -899,7 +809,6 @@ xmlEncodeSpecialChars(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlChar *input)
return(buffer);
mem_error:
- xmlEntitiesErrMemory("xmlEncodeSpecialChars: realloc failed");
xmlFree(buffer);
return(NULL);
}
@@ -956,27 +865,47 @@ xmlCopyEntity(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
xmlEntityPtr cur;
cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
- if (cur == NULL) {
- xmlEntitiesErrMemory("xmlCopyEntity:: malloc failed");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlEntity));
cur->type = XML_ENTITY_DECL;
cur->etype = ent->etype;
- if (ent->name != NULL)
+ if (ent->name != NULL) {
cur->name = xmlStrdup(ent->name);
- if (ent->ExternalID != NULL)
+ if (cur->name == NULL)
+ goto error;
+ }
+ if (ent->ExternalID != NULL) {
cur->ExternalID = xmlStrdup(ent->ExternalID);
- if (ent->SystemID != NULL)
+ if (cur->ExternalID == NULL)
+ goto error;
+ }
+ if (ent->SystemID != NULL) {
cur->SystemID = xmlStrdup(ent->SystemID);
- if (ent->content != NULL)
+ if (cur->SystemID == NULL)
+ goto error;
+ }
+ if (ent->content != NULL) {
cur->content = xmlStrdup(ent->content);
- if (ent->orig != NULL)
+ if (cur->content == NULL)
+ goto error;
+ }
+ if (ent->orig != NULL) {
cur->orig = xmlStrdup(ent->orig);
- if (ent->URI != NULL)
+ if (cur->orig == NULL)
+ goto error;
+ }
+ if (ent->URI != NULL) {
cur->URI = xmlStrdup(ent->URI);
+ if (cur->URI == NULL)
+ goto error;
+ }
return(cur);
+
+error:
+ xmlFreeEntity(cur);
+ return(NULL);
}
/**
@@ -989,52 +918,12 @@ xmlCopyEntity(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
*/
xmlEntitiesTablePtr
xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
- return(xmlHashCopy(table, xmlCopyEntity));
+ return(xmlHashCopySafe(table, xmlCopyEntity, xmlFreeEntityWrapper));
}
#endif /* LIBXML_TREE_ENABLED */
#ifdef LIBXML_OUTPUT_ENABLED
-/**
- * xmlDumpEntityContent:
- * @buf: An XML buffer.
- * @content: The entity content.
- *
- * This will dump the quoted string value, taking care of the special
- * treatment required by %
- */
-static void
-xmlDumpEntityContent(xmlBufferPtr buf, const xmlChar *content) {
- if (xmlStrchr(content, '%')) {
- const xmlChar * base, *cur;
-
- xmlBufferCCat(buf, "\"");
- base = cur = content;
- while (*cur != 0) {
- if (*cur == '"') {
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- xmlBufferAdd(buf, BAD_CAST """, 6);
- cur++;
- base = cur;
- } else if (*cur == '%') {
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- xmlBufferAdd(buf, BAD_CAST "%", 6);
- cur++;
- base = cur;
- } else {
- cur++;
- }
- }
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- xmlBufferCCat(buf, "\"");
- } else {
- xmlBufferWriteQuotedString(buf, content);
- }
-}
-
/**
* xmlDumpEntityDecl:
* @buf: An XML buffer.
@@ -1044,81 +933,15 @@ xmlDumpEntityContent(xmlBufferPtr buf, const xmlChar *content) {
*/
void
xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) {
- if ((buf == NULL) || (ent == NULL)) return;
- switch (ent->etype) {
- case XML_INTERNAL_GENERAL_ENTITY:
- xmlBufferWriteChar(buf, "name);
- xmlBufferWriteChar(buf, " ");
- if (ent->orig != NULL)
- xmlBufferWriteQuotedString(buf, ent->orig);
- else
- xmlDumpEntityContent(buf, ent->content);
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- xmlBufferWriteChar(buf, "name);
- if (ent->ExternalID != NULL) {
- xmlBufferWriteChar(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf, ent->ExternalID);
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- } else {
- xmlBufferWriteChar(buf, " SYSTEM ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- }
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- xmlBufferWriteChar(buf, "name);
- if (ent->ExternalID != NULL) {
- xmlBufferWriteChar(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf, ent->ExternalID);
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- } else {
- xmlBufferWriteChar(buf, " SYSTEM ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- }
- if (ent->content != NULL) { /* Should be true ! */
- xmlBufferWriteChar(buf, " NDATA ");
- if (ent->orig != NULL)
- xmlBufferWriteCHAR(buf, ent->orig);
- else
- xmlBufferWriteCHAR(buf, ent->content);
- }
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- xmlBufferWriteChar(buf, "name);
- xmlBufferWriteChar(buf, " ");
- if (ent->orig == NULL)
- xmlDumpEntityContent(buf, ent->content);
- else
- xmlBufferWriteQuotedString(buf, ent->orig);
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_EXTERNAL_PARAMETER_ENTITY:
- xmlBufferWriteChar(buf, "name);
- if (ent->ExternalID != NULL) {
- xmlBufferWriteChar(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf, ent->ExternalID);
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- } else {
- xmlBufferWriteChar(buf, " SYSTEM ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- }
- xmlBufferWriteChar(buf, ">\n");
- break;
- default:
- xmlEntitiesErr(XML_DTD_UNKNOWN_ENTITY,
- "xmlDumpEntitiesDecl: internal: unknown type entity type");
- }
+ xmlSaveCtxtPtr save;
+
+ if ((buf == NULL) || (ent == NULL))
+ return;
+
+ save = xmlSaveToBuffer(buf, NULL, 0);
+ xmlSaveTree(save, (xmlNodePtr) ent);
+ if (xmlSaveFinish(save) != XML_ERR_OK)
+ xmlFree(xmlBufferDetach(buf));
}
/**
@@ -1129,9 +952,9 @@ xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) {
* When using the hash table scan function, arguments need to be reversed
*/
static void
-xmlDumpEntityDeclScan(void *ent, void *buf,
+xmlDumpEntityDeclScan(void *ent, void *save,
const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlDumpEntityDecl((xmlBufferPtr) buf, (xmlEntityPtr) ent);
+ xmlSaveTree(save, ent);
}
/**
@@ -1143,6 +966,14 @@ xmlDumpEntityDeclScan(void *ent, void *buf,
*/
void
xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
- xmlHashScan(table, xmlDumpEntityDeclScan, buf);
+ xmlSaveCtxtPtr save;
+
+ if ((buf == NULL) || (table == NULL))
+ return;
+
+ save = xmlSaveToBuffer(buf, NULL, 0);
+ xmlHashScan(table, xmlDumpEntityDeclScan, save);
+ if (xmlSaveFinish(save) != XML_ERR_OK)
+ xmlFree(xmlBufferDetach(buf));
}
#endif /* LIBXML_OUTPUT_ENABLED */
diff --git a/error.c b/error.c
index c87cf2a..b678a0e 100644
--- a/error.c
+++ b/error.c
@@ -11,45 +11,169 @@
#include
#include
+#include
#include
#include
#include
#include "private/error.h"
+#include "private/string.h"
-#define XML_MAX_ERRORS 100
-
-#define XML_GET_VAR_STR(msg, str) { \
- int size, prev_size = -1; \
- int chars; \
- char *larger; \
- va_list ap; \
- \
- str = (char *) xmlMalloc(150); \
- if (str != NULL) { \
- \
- size = 150; \
- \
- while (size < 64000) { \
- va_start(ap, msg); \
- chars = vsnprintf(str, size, msg, ap); \
- va_end(ap); \
- if ((chars > -1) && (chars < size)) { \
- if (prev_size == chars) { \
- break; \
- } else { \
- prev_size = chars; \
- } \
- } \
- if (chars > -1) \
- size += chars + 1; \
- else \
- size += 100; \
- if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\
- break; \
- } \
- str = larger; \
- }} \
+/************************************************************************
+ * *
+ * Error struct *
+ * *
+ ************************************************************************/
+
+static int
+xmlVSetError(xmlError *err,
+ void *ctxt, xmlNodePtr node,
+ int domain, int code, xmlErrorLevel level,
+ const char *file, int line,
+ const char *str1, const char *str2, const char *str3,
+ int int1, int col,
+ const char *fmt, va_list ap)
+{
+ char *message = NULL;
+ char *fileCopy = NULL;
+ char *str1Copy = NULL;
+ char *str2Copy = NULL;
+ char *str3Copy = NULL;
+
+ if (code == XML_ERR_OK) {
+ xmlResetError(err);
+ return(0);
+ }
+
+ /*
+ * Formatting the message
+ */
+ if (fmt == NULL) {
+ message = xmlMemStrdup("No error message provided");
+ } else {
+ xmlChar *tmp;
+ int res;
+
+ res = xmlStrVASPrintf(&tmp, MAX_ERR_MSG_SIZE, fmt, ap);
+ if (res < 0)
+ goto err_memory;
+ message = (char *) tmp;
+ }
+ if (message == NULL)
+ goto err_memory;
+
+ if (file != NULL) {
+ fileCopy = (char *) xmlStrdup((const xmlChar *) file);
+ if (fileCopy == NULL)
+ goto err_memory;
+ }
+ if (str1 != NULL) {
+ str1Copy = (char *) xmlStrdup((const xmlChar *) str1);
+ if (str1Copy == NULL)
+ goto err_memory;
+ }
+ if (str2 != NULL) {
+ str2Copy = (char *) xmlStrdup((const xmlChar *) str2);
+ if (str2Copy == NULL)
+ goto err_memory;
+ }
+ if (str3 != NULL) {
+ str3Copy = (char *) xmlStrdup((const xmlChar *) str3);
+ if (str3Copy == NULL)
+ goto err_memory;
+ }
+
+ xmlResetError(err);
+
+ err->domain = domain;
+ err->code = code;
+ err->message = message;
+ err->level = level;
+ err->file = fileCopy;
+ err->line = line;
+ err->str1 = str1Copy;
+ err->str2 = str2Copy;
+ err->str3 = str3Copy;
+ err->int1 = int1;
+ err->int2 = col;
+ err->node = node;
+ err->ctxt = ctxt;
+
+ return(0);
+
+err_memory:
+ xmlFree(message);
+ xmlFree(fileCopy);
+ xmlFree(str1Copy);
+ xmlFree(str2Copy);
+ xmlFree(str3Copy);
+ return(-1);
+}
+
+static int LIBXML_ATTR_FORMAT(14,15)
+xmlSetError(xmlError *err,
+ void *ctxt, xmlNodePtr node,
+ int domain, int code, xmlErrorLevel level,
+ const char *file, int line,
+ const char *str1, const char *str2, const char *str3,
+ int int1, int col,
+ const char *fmt, ...)
+{
+ va_list ap;
+ int res;
+
+ va_start(ap, fmt);
+ res = xmlVSetError(err, ctxt, node, domain, code, level, file, line,
+ str1, str2, str3, int1, col, fmt, ap);
+ va_end(ap);
+
+ return(res);
+}
+
+static int
+xmlVUpdateError(xmlError *err,
+ void *ctxt, xmlNodePtr node,
+ int domain, int code, xmlErrorLevel level,
+ const char *file, int line,
+ const char *str1, const char *str2, const char *str3,
+ int int1, int col,
+ const char *fmt, va_list ap)
+{
+ int res;
+
+ /*
+ * Find first element parent.
+ */
+ if (node != NULL) {
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ if ((node->type == XML_ELEMENT_NODE) ||
+ (node->parent == NULL))
+ break;
+ node = node->parent;
+ }
+ }
+
+ /*
+ * Get file and line from node.
+ */
+ if (node != NULL) {
+ if ((file == NULL) && (node->doc != NULL))
+ file = (const char *) node->doc->URL;
+
+ if (line == 0) {
+ if (node->type == XML_ELEMENT_NODE)
+ line = node->line;
+ if ((line == 0) || (line == 65535))
+ line = xmlGetLineNo(node);
+ }
+ }
+
+ res = xmlVSetError(err, ctxt, node, domain, code, level, file, line,
+ str1, str2, str3, int1, col, fmt, ap);
+
+ return(res);
}
/************************************************************************
@@ -101,14 +225,21 @@ initGenericErrorDefaultFunc(xmlGenericErrorFunc * handler)
* @ctx: the new error handling context
* @handler: the new handler function
*
- * Function to reset the handler and the error context for out of
- * context error messages.
- * This simply means that @handler will be called for subsequent
- * error messages while not parsing nor validating. And @ctx will
- * be passed as first argument to @handler
- * One can simply force messages to be emitted to another FILE * than
- * stderr by setting @ctx to this file handle and @handler to NULL.
- * For multi-threaded applications, this must be set separately for each thread.
+ * DEPRECATED: See xmlSetStructuredErrorFunc for alternatives.
+ *
+ * Set the global "generic" handler and context for error messages.
+ * The generic error handler will only receive fragments of error
+ * messages which should be concatenated or printed to a stream.
+ *
+ * If handler is NULL, use the built-in default handler which prints
+ * to stderr.
+ *
+ * Since this is a global setting, it's a good idea to reset the
+ * error handler to its default value after collecting the errors
+ * you're interested in.
+ *
+ * For multi-threaded applications, this must be set separately for
+ * each thread.
*/
void
xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
@@ -124,12 +255,30 @@ xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
* @ctx: the new error handling context
* @handler: the new handler function
*
- * Function to reset the handler and the error context for out of
- * context structured error messages.
- * This simply means that @handler will be called for subsequent
- * error messages while not parsing nor validating. And @ctx will
- * be passed as first argument to @handler
- * For multi-threaded applications, this must be set separately for each thread.
+ * DEPRECATED: Use a per-context error handler.
+ *
+ * It's recommended to use the per-context error handlers instead:
+ *
+ * - xmlCtxtSetErrorHandler (since 2.13.0)
+ * - xmlTextReaderSetStructuredErrorHandler
+ * - xmlXPathSetErrorHandler (since 2.13.0)
+ * - xmlXIncludeSetErrorHandler (since 2.13.0)
+ * - xmlSchemaSetParserStructuredErrors
+ * - xmlSchemaSetValidStructuredErrors
+ * - xmlRelaxNGSetParserStructuredErrors
+ * - xmlRelaxNGSetValidStructuredErrors
+ *
+ * Set the global "structured" handler and context for error messages.
+ * If handler is NULL, the error handler is deactivated.
+ *
+ * The structured error handler takes precedence over "generic"
+ * handlers, even per-context generic handlers.
+ *
+ * Since this is a global setting, it's a good idea to deactivate the
+ * error handler after collecting the errors you're interested in.
+ *
+ * For multi-threaded applications, this must be set separately for
+ * each thread.
*/
void
xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
@@ -147,6 +296,8 @@ xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
* xmlParserPrintFileInfo:
* @input: an xmlParserInputPtr input
*
+ * DEPRECATED: Use xmlFormatError.
+ *
* Displays the associated file and line information for the current input
*/
@@ -238,6 +389,8 @@ xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
* xmlParserPrintFileContext:
* @input: an xmlParserInputPtr input
*
+ * DEPRECATED: Use xmlFormatError.
+ *
* Displays current context within the input content for error tracking
*/
void
@@ -247,35 +400,37 @@ xmlParserPrintFileContext(xmlParserInputPtr input) {
}
/**
- * xmlReportError:
- * @err: the error
- * @ctx: the parser context or NULL
- * @str: the formatted error message
+ * xmlFormatError:
+ * @err: the error
+ * @channel: callback
+ * @data: user data for callback
+ *
+ * Report a formatted error to a printf-like callback.
*
- * Report an error with its context, replace the 4 old error/warning
- * routines.
+ * This can result in a verbose multi-line report including additional
+ * information from the parser context.
+ *
+ * Available since 2.13.0.
*/
-static void
-xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
- xmlGenericErrorFunc channel, void *data)
+void
+xmlFormatError(const xmlError *err, xmlGenericErrorFunc channel, void *data)
{
- char *file = NULL;
- int line = 0;
- int code = -1;
+ const char *message;
+ const char *file;
+ int line;
+ int code;
int domain;
const xmlChar *name = NULL;
xmlNodePtr node;
xmlErrorLevel level;
+ xmlParserCtxtPtr ctxt = NULL;
xmlParserInputPtr input = NULL;
xmlParserInputPtr cur = NULL;
- if (err == NULL)
+ if ((err == NULL) || (channel == NULL))
return;
- if (channel == NULL) {
- channel = xmlGenericError;
- data = xmlGenericErrorContext;
- }
+ message = err->message;
file = err->file;
line = err->line;
code = err->code;
@@ -286,25 +441,30 @@ xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
if (code == XML_ERR_OK)
return;
- if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
+ if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
+ (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
+ (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
+ ctxt = err->ctxt;
+ }
+
+ if ((node != NULL) && (node->type == XML_ELEMENT_NODE) &&
+ (domain != XML_FROM_SCHEMASV))
name = node->name;
/*
* Maintain the compatibility with the legacy error handling
*/
- if (ctxt != NULL) {
+ if ((ctxt != NULL) && (ctxt->input != NULL)) {
input = ctxt->input;
- if ((input != NULL) && (input->filename == NULL) &&
+ if ((input->filename == NULL) &&
(ctxt->inputNr > 1)) {
cur = input;
input = ctxt->inputTab[ctxt->inputNr - 2];
}
- if (input != NULL) {
- if (input->filename)
- channel(data, "%s:%d: ", input->filename, input->line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: ", input->line);
- }
+ if (input->filename)
+ channel(data, "%s:%d: ", input->filename, input->line);
+ else if ((line != 0) && (domain == XML_FROM_PARSER))
+ channel(data, "Entity: line %d: ", input->line);
} else {
if (file != NULL)
channel(data, "%s:%d: ", file, line);
@@ -405,19 +565,35 @@ xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
channel(data, "error : ");
break;
}
- if (str != NULL) {
+ if (message != NULL) {
int len;
- len = xmlStrlen((const xmlChar *)str);
- if ((len > 0) && (str[len - 1] != '\n'))
- channel(data, "%s\n", str);
+ len = xmlStrlen((const xmlChar *) message);
+ if ((len > 0) && (message[len - 1] != '\n'))
+ channel(data, "%s\n", message);
else
- channel(data, "%s", str);
+ channel(data, "%s", message);
} else {
- channel(data, "%s\n", "out of memory error");
+ channel(data, "%s\n", "No error message provided");
}
if (ctxt != NULL) {
+ if ((input != NULL) &&
+ ((input->buf == NULL) || (input->buf->encoder == NULL)) &&
+ (code == XML_ERR_INVALID_ENCODING) &&
+ (input->cur < input->end)) {
+ int i;
+
+ channel(data, "Bytes:");
+ for (i = 0; i < 4; i++) {
+ if (input->cur + i >= input->end)
+ break;
+ channel(data, " 0x%02X", input->cur[i]);
+ }
+ channel(data, "\n");
+ }
+
xmlParserPrintFileContextInternal(input, channel, data);
+
if (cur != NULL) {
if (cur->filename)
channel(data, "%s:%d: \n", cur->filename, cur->line);
@@ -442,12 +618,53 @@ xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
}
/**
- * __xmlRaiseError:
+ * xmlRaiseMemoryError:
+ * @schannel: the structured callback channel
+ * @channel: the old callback channel
+ * @data: the callback data
+ * @domain: the domain for the error
+ * @error: optional error struct to be filled
+ *
+ * Update the global and optional error structure, then forward the
+ * error to an error handler.
+ *
+ * This function doesn't make memory allocations which are likely
+ * to fail after an OOM error.
+ */
+void
+xmlRaiseMemoryError(xmlStructuredErrorFunc schannel, xmlGenericErrorFunc channel,
+ void *data, int domain, xmlError *error)
+{
+ xmlError *lastError = &xmlLastError;
+
+ xmlResetLastError();
+ lastError->domain = domain;
+ lastError->code = XML_ERR_NO_MEMORY;
+ lastError->level = XML_ERR_FATAL;
+
+ if (error != NULL) {
+ xmlResetError(error);
+ error->domain = domain;
+ error->code = XML_ERR_NO_MEMORY;
+ error->level = XML_ERR_FATAL;
+ }
+
+ if (schannel != NULL) {
+ schannel(data, lastError);
+ } else if (xmlStructuredError != NULL) {
+ xmlStructuredError(xmlStructuredErrorContext, lastError);
+ } else if (channel != NULL) {
+ channel(data, "libxml2: out of memory\n");
+ }
+}
+
+/**
+ * xmlVRaiseError:
* @schannel: the structured callback channel
* @channel: the old callback channel
* @data: the callback data
* @ctx: the parser context or NULL
- * @ctx: the parser context or NULL
+ * @node: the current node or NULL
* @domain: the domain for the error
* @code: the code for the error
* @level: the xmlErrorLevel for the error
@@ -459,258 +676,128 @@ xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
* @int1: extra int info
* @col: column number of the error or 0 if N/A
* @msg: the message to display/transmit
- * @...: extra parameters for the message display
+ * @ap: extra parameters for the message display
*
* Update the appropriate global or contextual error structure,
* then forward the error message down the parser or generic
* error callback handler
+ *
+ * Returns 0 on success, -1 if a memory allocation failed.
*/
-void
-__xmlRaiseError(xmlStructuredErrorFunc schannel,
- xmlGenericErrorFunc channel, void *data, void *ctx,
- void *nod, int domain, int code, xmlErrorLevel level,
- const char *file, int line, const char *str1,
- const char *str2, const char *str3, int int1, int col,
- const char *msg, ...)
+int
+xmlVRaiseError(xmlStructuredErrorFunc schannel,
+ xmlGenericErrorFunc channel, void *data, void *ctx,
+ xmlNode *node, int domain, int code, xmlErrorLevel level,
+ const char *file, int line, const char *str1,
+ const char *str2, const char *str3, int int1, int col,
+ const char *msg, va_list ap)
{
xmlParserCtxtPtr ctxt = NULL;
- xmlNodePtr node = (xmlNodePtr) nod;
- char *str = NULL;
- xmlParserInputPtr input = NULL;
- xmlErrorPtr to = &xmlLastError;
- xmlNodePtr baseptr = NULL;
+ /* xmlLastError is a macro retrieving the per-thread global. */
+ xmlErrorPtr lastError = &xmlLastError;
+ xmlErrorPtr to = lastError;
if (code == XML_ERR_OK)
- return;
+ return(0);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ if (code == XML_ERR_INTERNAL_ERROR) {
+ fprintf(stderr, "Unexpected error: %d\n", code);
+ abort();
+ }
+#endif
if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING))
- return;
+ return(0);
+
if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
(domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
ctxt = (xmlParserCtxtPtr) ctx;
- if (ctxt != NULL) {
- if (level == XML_ERR_WARNING) {
- if (ctxt->nbWarnings >= XML_MAX_ERRORS)
- return;
- ctxt->nbWarnings += 1;
- } else {
- if (ctxt->nbErrors >= XML_MAX_ERRORS)
- return;
- ctxt->nbErrors += 1;
- }
-
- if ((schannel == NULL) && (ctxt->sax != NULL) &&
- (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
- (ctxt->sax->serror != NULL)) {
- schannel = ctxt->sax->serror;
- data = ctxt->userData;
- }
- }
- }
- /*
- * Check if structured error handler set
- */
- if (schannel == NULL) {
- schannel = xmlStructuredError;
- /*
- * if user has defined handler, change data ptr to user's choice
- */
- if (schannel != NULL)
- data = xmlStructuredErrorContext;
- }
- /*
- * Formatting the message
- */
- if (msg == NULL) {
- str = (char *) xmlStrdup(BAD_CAST "No error message provided");
- } else {
- XML_GET_VAR_STR(msg, str);
+ if (ctxt != NULL)
+ to = &ctxt->lastError;
}
- /*
- * specific processing if a parser context is provided
- */
- if (ctxt != NULL) {
- if (file == NULL) {
- input = ctxt->input;
- if ((input != NULL) && (input->filename == NULL) &&
- (ctxt->inputNr > 1)) {
- input = ctxt->inputTab[ctxt->inputNr - 2];
- }
- if (input != NULL) {
- file = input->filename;
- line = input->line;
- col = input->col;
- }
- }
- to = &ctxt->lastError;
- } else if ((node != NULL) && (file == NULL)) {
- int i;
-
- if ((node->doc != NULL) && (node->doc->URL != NULL)) {
- baseptr = node;
-/* file = (const char *) node->doc->URL; */
- }
- for (i = 0;
- ((i < 10) && (node != NULL) && (node->type != XML_ELEMENT_NODE));
- i++)
- node = node->parent;
- if ((baseptr == NULL) && (node != NULL) &&
- (node->doc != NULL) && (node->doc->URL != NULL))
- baseptr = node;
-
- if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
- line = node->line;
- if ((line == 0) || (line == 65535))
- line = xmlGetLineNo(node);
- }
+ if (xmlVUpdateError(to, ctxt, node, domain, code, level, file, line,
+ str1, str2, str3, int1, col, msg, ap))
+ return(-1);
- /*
- * Save the information about the error
- */
- xmlResetError(to);
- to->domain = domain;
- to->code = code;
- to->message = str;
- to->level = level;
- if (file != NULL)
- to->file = (char *) xmlStrdup((const xmlChar *) file);
- else if (baseptr != NULL) {
-#ifdef LIBXML_XINCLUDE_ENABLED
- /*
- * We check if the error is within an XInclude section and,
- * if so, attempt to print out the href of the XInclude instead
- * of the usual "base" (doc->URL) for the node (bug 152623).
- */
- xmlNodePtr prev = baseptr;
- char *href = NULL;
- int inclcount = 0;
- while (prev != NULL) {
- if (prev->prev == NULL)
- prev = prev->parent;
- else {
- prev = prev->prev;
- if (prev->type == XML_XINCLUDE_START) {
- if (inclcount > 0) {
- --inclcount;
- } else {
- href = (char *) xmlGetProp(prev, BAD_CAST "href");
- if (href != NULL)
- break;
- }
- } else if (prev->type == XML_XINCLUDE_END)
- inclcount++;
- }
- }
- if (href != NULL)
- to->file = href;
- else
-#endif
- to->file = (char *) xmlStrdup(baseptr->doc->URL);
- if ((to->file == NULL) && (node != NULL) && (node->doc != NULL)) {
- to->file = (char *) xmlStrdup(node->doc->URL);
- }
+ if (to != lastError) {
+ if (xmlCopyError(to, lastError) < 0)
+ return(-1);
}
- to->line = line;
- if (str1 != NULL)
- to->str1 = (char *) xmlStrdup((const xmlChar *) str1);
- if (str2 != NULL)
- to->str2 = (char *) xmlStrdup((const xmlChar *) str2);
- if (str3 != NULL)
- to->str3 = (char *) xmlStrdup((const xmlChar *) str3);
- to->int1 = int1;
- to->int2 = col;
- to->node = node;
- to->ctxt = ctx;
-
- if (to != &xmlLastError)
- xmlCopyError(to,&xmlLastError);
if (schannel != NULL) {
schannel(data, to);
- return;
- }
-
- /*
- * Find the callback channel if channel param is NULL
- */
- if ((ctxt != NULL) && (channel == NULL) &&
- (xmlStructuredError == NULL) && (ctxt->sax != NULL)) {
- if (level == XML_ERR_WARNING)
- channel = ctxt->sax->warning;
+ } else if (xmlStructuredError != NULL) {
+ xmlStructuredError(xmlStructuredErrorContext, to);
+ } else if (channel != NULL) {
+ /* Don't invoke legacy error handlers */
+ if ((channel == xmlGenericErrorDefaultFunc) ||
+ (channel == xmlParserError) ||
+ (channel == xmlParserWarning) ||
+ (channel == xmlParserValidityError) ||
+ (channel == xmlParserValidityWarning))
+ xmlFormatError(to, xmlGenericError, xmlGenericErrorContext);
else
- channel = ctxt->sax->error;
- data = ctxt->userData;
- } else if (channel == NULL) {
- channel = xmlGenericError;
- if (ctxt != NULL) {
- data = ctxt;
- } else {
- data = xmlGenericErrorContext;
- }
+ channel(data, "%s", to->message);
}
- if (channel == NULL)
- return;
- if ((channel == xmlParserError) ||
- (channel == xmlParserWarning) ||
- (channel == xmlParserValidityError) ||
- (channel == xmlParserValidityWarning))
- xmlReportError(to, ctxt, str, NULL, NULL);
- else if (((void(*)(void)) channel == (void(*)(void)) fprintf) ||
- (channel == xmlGenericErrorDefaultFunc))
- xmlReportError(to, ctxt, str, channel, data);
- else
- channel(data, "%s", str);
+ return(0);
}
/**
- * __xmlSimpleError:
- * @domain: where the error comes from
- * @code: the error code
- * @node: the context node
- * @extra: extra information
- *
- * Handle an out of memory condition
- */
-void
-__xmlSimpleError(int domain, int code, xmlNodePtr node,
- const char *msg, const char *extra)
-{
-
- if (code == XML_ERR_NO_MEMORY) {
- if (extra)
- __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
- else
- __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
- NULL, NULL, 0, 0, "Memory allocation failed\n");
- } else {
- __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
- code, XML_ERR_ERROR, NULL, 0, extra,
- NULL, NULL, 0, 0, msg, extra);
- }
-}
-/**
- * xmlParserError:
- * @ctx: an XML parser context
+ * __xmlRaiseError:
+ * @schannel: the structured callback channel
+ * @channel: the old callback channel
+ * @data: the callback data
+ * @ctx: the parser context or NULL
+ * @nod: the node or NULL
+ * @domain: the domain for the error
+ * @code: the code for the error
+ * @level: the xmlErrorLevel for the error
+ * @file: the file source of the error (or NULL)
+ * @line: the line of the error or 0 if N/A
+ * @str1: extra string info
+ * @str2: extra string info
+ * @str3: extra string info
+ * @int1: extra int info
+ * @col: column number of the error or 0 if N/A
* @msg: the message to display/transmit
* @...: extra parameters for the message display
*
- * Display and format an error messages, gives file, line, position and
- * extra parameters.
+ * Update the appropriate global or contextual error structure,
+ * then forward the error message down the parser or generic
+ * error callback handler
+ *
+ * Returns 0 on success, -1 if a memory allocation failed.
*/
-void
-xmlParserError(void *ctx, const char *msg, ...)
+int
+__xmlRaiseError(xmlStructuredErrorFunc schannel,
+ xmlGenericErrorFunc channel, void *data, void *ctx,
+ xmlNode *node, int domain, int code, xmlErrorLevel level,
+ const char *file, int line, const char *str1,
+ const char *str2, const char *str3, int int1, int col,
+ const char *msg, ...)
{
+ va_list ap;
+ int res;
+
+ va_start(ap, msg);
+ res = xmlVRaiseError(schannel, channel, data, ctx, node, domain, code,
+ level, file, line, str1, str2, str3, int1, col, msg,
+ ap);
+ va_end(ap);
+
+ return(res);
+}
+
+static void
+xmlVFormatLegacyError(void *ctx, const char *level,
+ const char *fmt, va_list ap) {
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlParserInputPtr input = NULL;
xmlParserInputPtr cur = NULL;
- char * str;
+ xmlChar *str = NULL;
if (ctxt != NULL) {
input = ctxt->input;
@@ -722,11 +809,13 @@ xmlParserError(void *ctx, const char *msg, ...)
xmlParserPrintFileInfo(input);
}
- xmlGenericError(xmlGenericErrorContext, "error: ");
- XML_GET_VAR_STR(msg, str);
- xmlGenericError(xmlGenericErrorContext, "%s", str);
- if (str != NULL)
+ xmlGenericError(xmlGenericErrorContext, "%s: ", level);
+
+ xmlStrVASPrintf(&str, MAX_ERR_MSG_SIZE, fmt, ap);
+ if (str != NULL) {
+ xmlGenericError(xmlGenericErrorContext, "%s", (char *) str);
xmlFree(str);
+ }
if (ctxt != NULL) {
xmlParserPrintFileContext(input);
@@ -739,54 +828,43 @@ xmlParserError(void *ctx, const char *msg, ...)
}
/**
- * xmlParserWarning:
+ * xmlParserError:
* @ctx: an XML parser context
* @msg: the message to display/transmit
* @...: extra parameters for the message display
*
- * Display and format a warning messages, gives file, line, position and
+ * Display and format an error messages, gives file, line, position and
* extra parameters.
*/
void
-xmlParserWarning(void *ctx, const char *msg, ...)
+xmlParserError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserInputPtr input = NULL;
- xmlParserInputPtr cur = NULL;
- char * str;
+ va_list ap;
- if (ctxt != NULL) {
- input = ctxt->input;
- if ((input != NULL) && (input->filename == NULL) &&
- (ctxt->inputNr > 1)) {
- cur = input;
- input = ctxt->inputTab[ctxt->inputNr - 2];
- }
- xmlParserPrintFileInfo(input);
- }
+ va_start(ap, msg);
+ xmlVFormatLegacyError(ctx, "error", msg, ap);
+ va_end(ap);
+}
- xmlGenericError(xmlGenericErrorContext, "warning: ");
- XML_GET_VAR_STR(msg, str);
- xmlGenericError(xmlGenericErrorContext, "%s", str);
- if (str != NULL)
- xmlFree(str);
+/**
+ * xmlParserWarning:
+ * @ctx: an XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format a warning messages, gives file, line, position and
+ * extra parameters.
+ */
+void
+xmlParserWarning(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
+{
+ va_list ap;
- if (ctxt != NULL) {
- xmlParserPrintFileContext(input);
- if (cur != NULL) {
- xmlParserPrintFileInfo(cur);
- xmlGenericError(xmlGenericErrorContext, "\n");
- xmlParserPrintFileContext(cur);
- }
- }
+ va_start(ap, msg);
+ xmlVFormatLegacyError(ctx, "warning", msg, ap);
+ va_end(ap);
}
-/************************************************************************
- * *
- * Handling of validation errors *
- * *
- ************************************************************************/
-
/**
* xmlParserValidityError:
* @ctx: an XML parser context
@@ -797,38 +875,13 @@ xmlParserWarning(void *ctx, const char *msg, ...)
* line, position and extra parameters.
*/
void
-xmlParserValidityError(void *ctx, const char *msg, ...)
+xmlParserValidityError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserInputPtr input = NULL;
- char * str;
- int len = xmlStrlen((const xmlChar *) msg);
- static int had_info = 0;
-
- if ((len > 1) && (msg[len - 2] != ':')) {
- if (ctxt != NULL) {
- input = ctxt->input;
- if ((input->filename == NULL) && (ctxt->inputNr > 1))
- input = ctxt->inputTab[ctxt->inputNr - 2];
-
- if (had_info == 0) {
- xmlParserPrintFileInfo(input);
- }
- }
- xmlGenericError(xmlGenericErrorContext, "validity error: ");
- had_info = 0;
- } else {
- had_info = 1;
- }
+ va_list ap;
- XML_GET_VAR_STR(msg, str);
- xmlGenericError(xmlGenericErrorContext, "%s", str);
- if (str != NULL)
- xmlFree(str);
-
- if ((ctxt != NULL) && (input != NULL)) {
- xmlParserPrintFileContext(input);
- }
+ va_start(ap, msg);
+ xmlVFormatLegacyError(ctx, "validity error", msg, ap);
+ va_end(ap);
}
/**
@@ -841,30 +894,13 @@ xmlParserValidityError(void *ctx, const char *msg, ...)
* position and extra parameters.
*/
void
-xmlParserValidityWarning(void *ctx, const char *msg, ...)
+xmlParserValidityWarning(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserInputPtr input = NULL;
- char * str;
- int len = xmlStrlen((const xmlChar *) msg);
-
- if ((ctxt != NULL) && (len != 0) && (msg[len - 1] != ':')) {
- input = ctxt->input;
- if ((input->filename == NULL) && (ctxt->inputNr > 1))
- input = ctxt->inputTab[ctxt->inputNr - 2];
+ va_list ap;
- xmlParserPrintFileInfo(input);
- }
-
- xmlGenericError(xmlGenericErrorContext, "validity warning: ");
- XML_GET_VAR_STR(msg, str);
- xmlGenericError(xmlGenericErrorContext, "%s", str);
- if (str != NULL)
- xmlFree(str);
-
- if (ctxt != NULL) {
- xmlParserPrintFileContext(input);
- }
+ va_start(ap, msg);
+ xmlVFormatLegacyError(ctx, "validity warning", msg, ap);
+ va_end(ap);
}
@@ -982,42 +1018,351 @@ xmlCtxtResetLastError(void *ctx)
*/
int
xmlCopyError(const xmlError *from, xmlErrorPtr to) {
- char *message, *file, *str1, *str2, *str3;
+ const char *fmt = NULL;
if ((from == NULL) || (to == NULL))
return(-1);
- message = (char *) xmlStrdup((xmlChar *) from->message);
- file = (char *) xmlStrdup ((xmlChar *) from->file);
- str1 = (char *) xmlStrdup ((xmlChar *) from->str1);
- str2 = (char *) xmlStrdup ((xmlChar *) from->str2);
- str3 = (char *) xmlStrdup ((xmlChar *) from->str3);
-
- if (to->message != NULL)
- xmlFree(to->message);
- if (to->file != NULL)
- xmlFree(to->file);
- if (to->str1 != NULL)
- xmlFree(to->str1);
- if (to->str2 != NULL)
- xmlFree(to->str2);
- if (to->str3 != NULL)
- xmlFree(to->str3);
- to->domain = from->domain;
- to->code = from->code;
- to->level = from->level;
- to->line = from->line;
- to->node = from->node;
- to->int1 = from->int1;
- to->int2 = from->int2;
- to->node = from->node;
- to->ctxt = from->ctxt;
- to->message = message;
- to->file = file;
- to->str1 = str1;
- to->str2 = str2;
- to->str3 = str3;
-
- return 0;
+ if (from->message != NULL)
+ fmt = "%s";
+
+ return(xmlSetError(to, from->ctxt, from->node,
+ from->domain, from->code, from->level,
+ from->file, from->line,
+ from->str1, from->str2, from->str3,
+ from->int1, from->int2,
+ fmt, from->message));
}
+/**
+ * xmlErrString:
+ * @code: an xmlParserErrors code
+ *
+ * Returns an error message for a code.
+ */
+const char *
+xmlErrString(xmlParserErrors code) {
+ const char *errmsg;
+
+ switch (code) {
+ case XML_ERR_INVALID_HEX_CHARREF:
+ errmsg = "CharRef: invalid hexadecimal value";
+ break;
+ case XML_ERR_INVALID_DEC_CHARREF:
+ errmsg = "CharRef: invalid decimal value";
+ break;
+ case XML_ERR_INVALID_CHARREF:
+ errmsg = "CharRef: invalid value";
+ break;
+ case XML_ERR_INTERNAL_ERROR:
+ errmsg = "internal error";
+ break;
+ case XML_ERR_PEREF_AT_EOF:
+ errmsg = "PEReference at end of document";
+ break;
+ case XML_ERR_PEREF_IN_PROLOG:
+ errmsg = "PEReference in prolog";
+ break;
+ case XML_ERR_PEREF_IN_EPILOG:
+ errmsg = "PEReference in epilog";
+ break;
+ case XML_ERR_PEREF_NO_NAME:
+ errmsg = "PEReference: no name";
+ break;
+ case XML_ERR_PEREF_SEMICOL_MISSING:
+ errmsg = "PEReference: expecting ';'";
+ break;
+ case XML_ERR_ENTITY_LOOP:
+ errmsg = "Detected an entity reference loop";
+ break;
+ case XML_ERR_ENTITY_NOT_STARTED:
+ errmsg = "EntityValue: \" or ' expected";
+ break;
+ case XML_ERR_ENTITY_PE_INTERNAL:
+ errmsg = "PEReferences forbidden in internal subset";
+ break;
+ case XML_ERR_ENTITY_NOT_FINISHED:
+ errmsg = "EntityValue: \" or ' expected";
+ break;
+ case XML_ERR_ATTRIBUTE_NOT_STARTED:
+ errmsg = "AttValue: \" or ' expected";
+ break;
+ case XML_ERR_LT_IN_ATTRIBUTE:
+ errmsg = "Unescaped '<' not allowed in attributes values";
+ break;
+ case XML_ERR_LITERAL_NOT_STARTED:
+ errmsg = "SystemLiteral \" or ' expected";
+ break;
+ case XML_ERR_LITERAL_NOT_FINISHED:
+ errmsg = "Unfinished System or Public ID \" or ' expected";
+ break;
+ case XML_ERR_MISPLACED_CDATA_END:
+ errmsg = "Sequence ']]>' not allowed in content";
+ break;
+ case XML_ERR_URI_REQUIRED:
+ errmsg = "SYSTEM or PUBLIC, the URI is missing";
+ break;
+ case XML_ERR_PUBID_REQUIRED:
+ errmsg = "PUBLIC, the Public Identifier is missing";
+ break;
+ case XML_ERR_HYPHEN_IN_COMMENT:
+ errmsg = "Comment must not contain '--' (double-hyphen)";
+ break;
+ case XML_ERR_PI_NOT_STARTED:
+ errmsg = "xmlParsePI : no target name";
+ break;
+ case XML_ERR_RESERVED_XML_NAME:
+ errmsg = "Invalid PI name";
+ break;
+ case XML_ERR_NOTATION_NOT_STARTED:
+ errmsg = "NOTATION: Name expected here";
+ break;
+ case XML_ERR_NOTATION_NOT_FINISHED:
+ errmsg = "'>' required to close NOTATION declaration";
+ break;
+ case XML_ERR_VALUE_REQUIRED:
+ errmsg = "Entity value required";
+ break;
+ case XML_ERR_URI_FRAGMENT:
+ errmsg = "Fragment not allowed";
+ break;
+ case XML_ERR_ATTLIST_NOT_STARTED:
+ errmsg = "'(' required to start ATTLIST enumeration";
+ break;
+ case XML_ERR_NMTOKEN_REQUIRED:
+ errmsg = "NmToken expected in ATTLIST enumeration";
+ break;
+ case XML_ERR_ATTLIST_NOT_FINISHED:
+ errmsg = "')' required to finish ATTLIST enumeration";
+ break;
+ case XML_ERR_MIXED_NOT_STARTED:
+ errmsg = "MixedContentDecl : '|' or ')*' expected";
+ break;
+ case XML_ERR_PCDATA_REQUIRED:
+ errmsg = "MixedContentDecl : '#PCDATA' expected";
+ break;
+ case XML_ERR_ELEMCONTENT_NOT_STARTED:
+ errmsg = "ContentDecl : Name or '(' expected";
+ break;
+ case XML_ERR_ELEMCONTENT_NOT_FINISHED:
+ errmsg = "ContentDecl : ',' '|' or ')' expected";
+ break;
+ case XML_ERR_PEREF_IN_INT_SUBSET:
+ errmsg =
+ "PEReference: forbidden within markup decl in internal subset";
+ break;
+ case XML_ERR_GT_REQUIRED:
+ errmsg = "expected '>'";
+ break;
+ case XML_ERR_CONDSEC_INVALID:
+ errmsg = "XML conditional section '[' expected";
+ break;
+ case XML_ERR_INT_SUBSET_NOT_FINISHED:
+ errmsg = "Content error in the internal subset";
+ break;
+ case XML_ERR_EXT_SUBSET_NOT_FINISHED:
+ errmsg = "Content error in the external subset";
+ break;
+ case XML_ERR_CONDSEC_INVALID_KEYWORD:
+ errmsg =
+ "conditional section INCLUDE or IGNORE keyword expected";
+ break;
+ case XML_ERR_CONDSEC_NOT_FINISHED:
+ errmsg = "XML conditional section not closed";
+ break;
+ case XML_ERR_XMLDECL_NOT_STARTED:
+ errmsg = "Text declaration '' expected";
+ break;
+ case XML_ERR_EXT_ENTITY_STANDALONE:
+ errmsg = "external parsed entities cannot be standalone";
+ break;
+ case XML_ERR_ENTITYREF_SEMICOL_MISSING:
+ errmsg = "EntityRef: expecting ';'";
+ break;
+ case XML_ERR_DOCTYPE_NOT_FINISHED:
+ errmsg = "DOCTYPE improperly terminated";
+ break;
+ case XML_ERR_LTSLASH_REQUIRED:
+ errmsg = "EndTag: '' not found";
+ break;
+ case XML_ERR_EQUAL_REQUIRED:
+ errmsg = "expected '='";
+ break;
+ case XML_ERR_STRING_NOT_CLOSED:
+ errmsg = "String not closed expecting \" or '";
+ break;
+ case XML_ERR_STRING_NOT_STARTED:
+ errmsg = "String not started expecting ' or \"";
+ break;
+ case XML_ERR_ENCODING_NAME:
+ errmsg = "Invalid XML encoding name";
+ break;
+ case XML_ERR_STANDALONE_VALUE:
+ errmsg = "standalone accepts only 'yes' or 'no'";
+ break;
+ case XML_ERR_DOCUMENT_EMPTY:
+ errmsg = "Document is empty";
+ break;
+ case XML_ERR_DOCUMENT_END:
+ errmsg = "Extra content at the end of the document";
+ break;
+ case XML_ERR_NOT_WELL_BALANCED:
+ errmsg = "chunk is not well balanced";
+ break;
+ case XML_ERR_EXTRA_CONTENT:
+ errmsg = "extra content at the end of well balanced chunk";
+ break;
+ case XML_ERR_VERSION_MISSING:
+ errmsg = "Malformed declaration expecting version";
+ break;
+ case XML_ERR_NAME_TOO_LONG:
+ errmsg = "Name too long";
+ break;
+ case XML_ERR_INVALID_ENCODING:
+ errmsg = "Invalid bytes in character encoding";
+ break;
+ case XML_ERR_RESOURCE_LIMIT:
+ errmsg = "Resource limit exceeded";
+ break;
+ case XML_ERR_ARGUMENT:
+ errmsg = "Invalid argument";
+ break;
+ case XML_ERR_SYSTEM:
+ errmsg = "Out of system resources";
+ break;
+ case XML_ERR_REDECL_PREDEF_ENTITY:
+ errmsg = "Invalid redeclaration of predefined entity";
+ break;
+ case XML_ERR_UNSUPPORTED_ENCODING:
+ errmsg = "Unsupported encoding";
+ break;
+ case XML_ERR_INVALID_CHAR:
+ errmsg = "Invalid character";
+ break;
+
+ case XML_IO_UNKNOWN:
+ errmsg = "Unknown IO error"; break;
+ case XML_IO_EACCES:
+ errmsg = "Permission denied"; break;
+ case XML_IO_EAGAIN:
+ errmsg = "Resource temporarily unavailable"; break;
+ case XML_IO_EBADF:
+ errmsg = "Bad file descriptor"; break;
+ case XML_IO_EBADMSG:
+ errmsg = "Bad message"; break;
+ case XML_IO_EBUSY:
+ errmsg = "Resource busy"; break;
+ case XML_IO_ECANCELED:
+ errmsg = "Operation canceled"; break;
+ case XML_IO_ECHILD:
+ errmsg = "No child processes"; break;
+ case XML_IO_EDEADLK:
+ errmsg = "Resource deadlock avoided"; break;
+ case XML_IO_EDOM:
+ errmsg = "Domain error"; break;
+ case XML_IO_EEXIST:
+ errmsg = "File exists"; break;
+ case XML_IO_EFAULT:
+ errmsg = "Bad address"; break;
+ case XML_IO_EFBIG:
+ errmsg = "File too large"; break;
+ case XML_IO_EINPROGRESS:
+ errmsg = "Operation in progress"; break;
+ case XML_IO_EINTR:
+ errmsg = "Interrupted function call"; break;
+ case XML_IO_EINVAL:
+ errmsg = "Invalid argument"; break;
+ case XML_IO_EIO:
+ errmsg = "Input/output error"; break;
+ case XML_IO_EISDIR:
+ errmsg = "Is a directory"; break;
+ case XML_IO_EMFILE:
+ errmsg = "Too many open files"; break;
+ case XML_IO_EMLINK:
+ errmsg = "Too many links"; break;
+ case XML_IO_EMSGSIZE:
+ errmsg = "Inappropriate message buffer length"; break;
+ case XML_IO_ENAMETOOLONG:
+ errmsg = "Filename too long"; break;
+ case XML_IO_ENFILE:
+ errmsg = "Too many open files in system"; break;
+ case XML_IO_ENODEV:
+ errmsg = "No such device"; break;
+ case XML_IO_ENOENT:
+ errmsg = "No such file or directory"; break;
+ case XML_IO_ENOEXEC:
+ errmsg = "Exec format error"; break;
+ case XML_IO_ENOLCK:
+ errmsg = "No locks available"; break;
+ case XML_IO_ENOMEM:
+ errmsg = "Not enough space"; break;
+ case XML_IO_ENOSPC:
+ errmsg = "No space left on device"; break;
+ case XML_IO_ENOSYS:
+ errmsg = "Function not implemented"; break;
+ case XML_IO_ENOTDIR:
+ errmsg = "Not a directory"; break;
+ case XML_IO_ENOTEMPTY:
+ errmsg = "Directory not empty"; break;
+ case XML_IO_ENOTSUP:
+ errmsg = "Not supported"; break;
+ case XML_IO_ENOTTY:
+ errmsg = "Inappropriate I/O control operation"; break;
+ case XML_IO_ENXIO:
+ errmsg = "No such device or address"; break;
+ case XML_IO_EPERM:
+ errmsg = "Operation not permitted"; break;
+ case XML_IO_EPIPE:
+ errmsg = "Broken pipe"; break;
+ case XML_IO_ERANGE:
+ errmsg = "Result too large"; break;
+ case XML_IO_EROFS:
+ errmsg = "Read-only file system"; break;
+ case XML_IO_ESPIPE:
+ errmsg = "Invalid seek"; break;
+ case XML_IO_ESRCH:
+ errmsg = "No such process"; break;
+ case XML_IO_ETIMEDOUT:
+ errmsg = "Operation timed out"; break;
+ case XML_IO_EXDEV:
+ errmsg = "Improper link"; break;
+ case XML_IO_NETWORK_ATTEMPT:
+ errmsg = "Attempt to load network entity"; break;
+ case XML_IO_ENCODER:
+ errmsg = "encoder error"; break;
+ case XML_IO_FLUSH:
+ errmsg = "flush error"; break;
+ case XML_IO_WRITE:
+ errmsg = "write error"; break;
+ case XML_IO_NO_INPUT:
+ errmsg = "no input"; break;
+ case XML_IO_BUFFER_FULL:
+ errmsg = "buffer full"; break;
+ case XML_IO_LOAD_ERROR:
+ errmsg = "loading error"; break;
+ case XML_IO_ENOTSOCK:
+ errmsg = "not a socket"; break;
+ case XML_IO_EISCONN:
+ errmsg = "already connected"; break;
+ case XML_IO_ECONNREFUSED:
+ errmsg = "connection refused"; break;
+ case XML_IO_ENETUNREACH:
+ errmsg = "unreachable network"; break;
+ case XML_IO_EADDRINUSE:
+ errmsg = "address in use"; break;
+ case XML_IO_EALREADY:
+ errmsg = "already in use"; break;
+ case XML_IO_EAFNOSUPPORT:
+ errmsg = "unknown address family"; break;
+ case XML_IO_UNSUPPORTED_PROTOCOL:
+ errmsg = "unsupported protocol"; break;
+
+ default:
+ errmsg = "Unregistered error message";
+ }
+
+ return(errmsg);
+}
diff --git a/globals.c b/globals.c
index 7ed67d7..d5ef206 100644
--- a/globals.c
+++ b/globals.c
@@ -20,13 +20,13 @@
#include
#include
#include
-#include
#include
#include
#include
#include
#include
+#include "private/dict.h"
#include "private/error.h"
#include "private/globals.h"
#include "private/threads.h"
@@ -76,10 +76,13 @@ struct _xmlGlobalState {
void *waitHandle;
#endif
+#ifdef LIBXML_THREAD_ENABLED
+ unsigned localRngState[2];
+#endif
+
#define XML_OP XML_DECLARE_MEMBER
XML_GLOBALS_ALLOC
XML_GLOBALS_ERROR
-XML_GLOBALS_HTML
XML_GLOBALS_IO
XML_GLOBALS_PARSER
XML_GLOBALS_TREE
@@ -164,17 +167,14 @@ xmlFreeGlobalState(void *state);
* *
************************************************************************/
+#ifdef LIBXML_THREAD_ENABLED
+static unsigned xmlMainThreadRngState[2];
+#endif
+
/*
* Memory allocation routines
*/
-#if defined(DEBUG_MEMORY_LOCATION)
-xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
-xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
-xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc;
-xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
-xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
-#else
/**
* xmlFree:
* @mem: an already allocated block of memory
@@ -233,7 +233,6 @@ xmlPosixStrdup(const char *cur) {
* Returns the copy of the string or NULL in case of error
*/
xmlStrdupFunc xmlMemStrdup = xmlPosixStrdup;
-#endif /* DEBUG_MEMORY_LOCATION */
/**
* xmlBufferAllocScheme:
@@ -264,7 +263,7 @@ static int xmlDefaultBufferSizeThrDef = BASE_BUFFER_SIZE;
*
* Global setting, DEPRECATED.
*/
-int oldXMLWDcompatibility = 0; /* DEPRECATED */
+const int oldXMLWDcompatibility = 0; /* DEPRECATED */
/**
* xmlParserDebugEntities:
*
@@ -274,8 +273,7 @@ int oldXMLWDcompatibility = 0; /* DEPRECATED */
* while handling entities.
* Disabled by default
*/
-int xmlParserDebugEntities = 0;
-static int xmlParserDebugEntitiesThrDef = 0;
+const int xmlParserDebugEntities = 0;
/**
* xmlDoValidityCheckingDefaultValue:
*
@@ -289,7 +287,7 @@ static int xmlDoValidityCheckingDefaultValueThrDef = 0;
/**
* xmlGetWarningsDefaultValue:
*
- * DEPRECATED: Don't use
+ * DEPRECATED: Use the modern options API with XML_PARSE_NOWARNING.
*
* Global setting, indicate that the DTD validation should provide warnings.
* Activated by default.
@@ -460,7 +458,7 @@ static int xmlSaveNoEmptyTagsThrDef = 0;
*
* Default SAX version1 handler for XML, builds the DOM tree
*/
-xmlSAXHandlerV1 xmlDefaultSAXHandler = {
+const xmlSAXHandlerV1 xmlDefaultSAXHandler = {
xmlSAX2InternalSubset,
xmlSAX2IsStandalone,
xmlSAX2HasInternalSubset,
@@ -500,7 +498,7 @@ xmlSAXHandlerV1 xmlDefaultSAXHandler = {
* The default SAX Locator
* { getPublicId, getSystemId, getLineNumber, getColumnNumber}
*/
-xmlSAXLocator xmlDefaultSAXLocator = {
+const xmlSAXLocator xmlDefaultSAXLocator = {
xmlSAX2GetPublicId,
xmlSAX2GetSystemId,
xmlSAX2GetLineNumber,
@@ -516,7 +514,7 @@ xmlSAXLocator xmlDefaultSAXLocator = {
*
* Default old SAX v1 handler for HTML, builds the DOM tree
*/
-xmlSAXHandlerV1 htmlDefaultSAXHandler = {
+const xmlSAXHandlerV1 htmlDefaultSAXHandler = {
xmlSAX2InternalSubset,
NULL,
NULL,
@@ -596,6 +594,11 @@ void xmlInitGlobalsInternal(void) {
#endif
mainthread = GetCurrentThreadId();
#endif
+
+#ifdef LIBXML_THREAD_ENABLED
+ xmlMainThreadRngState[0] = xmlGlobalRandom();
+ xmlMainThreadRngState[1] = xmlGlobalRandom();
+#endif
}
/**
@@ -756,36 +759,21 @@ static void
xmlInitGlobalState(xmlGlobalStatePtr gs) {
xmlMutexLock(&xmlThrDefMutex);
-#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_LEGACY_ENABLED) && defined(LIBXML_SAX1_ENABLED)
- inithtmlDefaultSAXHandler(&gs->gs_htmlDefaultSAXHandler);
+#ifdef LIBXML_THREAD_ENABLED
+ gs->localRngState[0] = xmlGlobalRandom();
+ gs->localRngState[1] = xmlGlobalRandom();
#endif
- gs->gs_oldXMLWDcompatibility = 0;
gs->gs_xmlBufferAllocScheme = xmlBufferAllocSchemeThrDef;
gs->gs_xmlDefaultBufferSize = xmlDefaultBufferSizeThrDef;
-#if defined(LIBXML_SAX1_ENABLED) && defined(LIBXML_LEGACY_ENABLED)
- initxmlDefaultSAXHandler(&gs->gs_xmlDefaultSAXHandler, 1);
-#endif /* LIBXML_SAX1_ENABLED */
- gs->gs_xmlDefaultSAXLocator.getPublicId = xmlSAX2GetPublicId;
- gs->gs_xmlDefaultSAXLocator.getSystemId = xmlSAX2GetSystemId;
- gs->gs_xmlDefaultSAXLocator.getLineNumber = xmlSAX2GetLineNumber;
- gs->gs_xmlDefaultSAXLocator.getColumnNumber = xmlSAX2GetColumnNumber;
gs->gs_xmlDoValidityCheckingDefaultValue =
xmlDoValidityCheckingDefaultValueThrDef;
#ifdef LIBXML_THREAD_ALLOC_ENABLED
-#ifdef DEBUG_MEMORY_LOCATION
- gs->gs_xmlFree = xmlMemFree;
- gs->gs_xmlMalloc = xmlMemMalloc;
- gs->gs_xmlMallocAtomic = xmlMemMalloc;
- gs->gs_xmlRealloc = xmlMemRealloc;
- gs->gs_xmlMemStrdup = xmlMemoryStrdup;
-#else
gs->gs_xmlFree = free;
gs->gs_xmlMalloc = malloc;
gs->gs_xmlMallocAtomic = malloc;
gs->gs_xmlRealloc = realloc;
gs->gs_xmlMemStrdup = xmlPosixStrdup;
-#endif
#endif
gs->gs_xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef;
#ifdef LIBXML_OUTPUT_ENABLED
@@ -796,7 +784,6 @@ xmlInitGlobalState(xmlGlobalStatePtr gs) {
gs->gs_xmlKeepBlanksDefaultValue = xmlKeepBlanksDefaultValueThrDef;
gs->gs_xmlLineNumbersDefaultValue = xmlLineNumbersDefaultValueThrDef;
gs->gs_xmlLoadExtDtdDefaultValue = xmlLoadExtDtdDefaultValueThrDef;
- gs->gs_xmlParserDebugEntities = xmlParserDebugEntitiesThrDef;
gs->gs_xmlPedanticParserDefaultValue = xmlPedanticParserDefaultValueThrDef;
gs->gs_xmlSubstituteEntitiesDefaultValue =
xmlSubstituteEntitiesDefaultValueThrDef;
@@ -904,12 +891,26 @@ xmlGetThreadLocalStorage(int allowFailure) {
#define XML_OP XML_DEFINE_GLOBAL_WRAPPER
XML_GLOBALS_ALLOC
XML_GLOBALS_ERROR
-XML_GLOBALS_HTML
XML_GLOBALS_IO
XML_GLOBALS_PARSER
XML_GLOBALS_TREE
#undef XML_OP
+#ifdef LIBXML_THREAD_ENABLED
+/**
+ * xmlGetLocalRngState:
+ *
+ * Returns the local RNG state.
+ */
+unsigned *
+xmlGetLocalRngState(void) {
+ if (IS_MAIN_THREAD)
+ return(xmlMainThreadRngState);
+ else
+ return(xmlGetThreadLocalStorage(0)->localRngState);
+}
+#endif
+
/* For backward compatibility */
const char *const *
@@ -917,6 +918,35 @@ __xmlParserVersion(void) {
return &xmlParserVersion;
}
+const int *
+__oldXMLWDcompatibility(void) {
+ return &oldXMLWDcompatibility;
+}
+
+const int *
+__xmlParserDebugEntities(void) {
+ return &xmlParserDebugEntities;
+}
+
+const xmlSAXLocator *
+__xmlDefaultSAXLocator(void) {
+ return &xmlDefaultSAXLocator;
+}
+
+#ifdef LIBXML_SAX1_ENABLED
+const xmlSAXHandlerV1 *
+__xmlDefaultSAXHandler(void) {
+ return &xmlDefaultSAXHandler;
+}
+
+#ifdef LIBXML_HTML_ENABLED
+const xmlSAXHandlerV1 *
+__htmlDefaultSAXHandler(void) {
+ return &htmlDefaultSAXHandler;
+}
+#endif /* LIBXML_HTML_ENABLED */
+#endif /* LIBXML_SAX1_ENABLED */
+
#endif /* LIBXML_THREAD_ENABLED */
/**
@@ -950,6 +980,8 @@ xmlCheckThreadLocalStorage(void) {
return(0);
}
+/** DOC_DISABLE */
+
/**
* DllMain:
* @hinstDLL: handle to DLL instance
@@ -1115,13 +1147,8 @@ int xmlThrDefLoadExtDtdDefaultValue(int v) {
return ret;
}
-int xmlThrDefParserDebugEntities(int v) {
- int ret;
- xmlMutexLock(&xmlThrDefMutex);
- ret = xmlParserDebugEntitiesThrDef;
- xmlParserDebugEntitiesThrDef = v;
- xmlMutexUnlock(&xmlThrDefMutex);
- return ret;
+int xmlThrDefParserDebugEntities(int v ATTRIBUTE_UNUSED) {
+ return(xmlParserDebugEntities);
}
int xmlThrDefPedanticParserDefaultValue(int v) {
@@ -1207,3 +1234,5 @@ xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc fun
return(old);
}
+/** DOC_ENABLE */
+
diff --git a/hash.c b/hash.c
index 38341d7..6af8527 100644
--- a/hash.c
+++ b/hash.c
@@ -445,16 +445,9 @@ xmlHashUpdateInternal(xmlHashTablePtr hash, const xmlChar *key,
if (dealloc)
dealloc(entry->payload, entry->key);
entry->payload = payload;
- return(0);
- } else {
- /*
- * xmlHashAddEntry found an existing entry.
- *
- * TODO: We should return a different error code here to
- * distinguish from malloc failures.
- */
- return(-1);
}
+
+ return(0);
}
/*
@@ -589,7 +582,7 @@ xmlHashUpdateInternal(xmlHashTablePtr hash, const xmlChar *key,
hash->nbElems++;
- return(0);
+ return(1);
}
/**
@@ -604,6 +597,70 @@ xmlHashDefaultDeallocator(void *entry, const xmlChar *key ATTRIBUTE_UNUSED) {
xmlFree(entry);
}
+/**
+ * xmlHashAdd:
+ * @hash: hash table
+ * @key: string key
+ * @payload: pointer to the payload
+ *
+ * Add a hash table entry. If an entry with this key already exists,
+ * payload will not be updated and 0 is returned. This return value
+ * can't be distinguished from out-of-memory errors, so this function
+ * should be used with care.
+ *
+ * Available since 2.13.0.
+ *
+ * Returns 1 on success, 0 if an entry exists and -1 in case of error.
+ */
+int
+xmlHashAdd(xmlHashTablePtr hash, const xmlChar *key, void *payload) {
+ return(xmlHashUpdateInternal(hash, key, NULL, NULL, payload, NULL, 0));
+}
+
+/**
+ * xmlHashAdd2:
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @payload: pointer to the payload
+ *
+ * Add a hash table entry with two strings as key.
+ *
+ * See xmlHashAdd.
+ *
+ * Available since 2.13.0.
+ *
+ * Returns 1 on success, 0 if an entry exists and -1 in case of error.
+ */
+int
+xmlHashAdd2(xmlHashTablePtr hash, const xmlChar *key,
+ const xmlChar *key2, void *payload) {
+ return(xmlHashUpdateInternal(hash, key, key2, NULL, payload, NULL, 0));
+}
+
+/**
+ * xmlHashAdd3:
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @key3: third string key
+ * @payload: pointer to the payload
+ *
+ * Add a hash table entry with three strings as key.
+ *
+ * See xmlHashAdd.
+ *
+ * Available since 2.13.0.
+ *
+ * Returns 1 on success, 0 if an entry exists and -1 in case of error.
+ */
+int
+xmlHashAdd3(xmlHashTablePtr hash, const xmlChar *key,
+ const xmlChar *key2, const xmlChar *key3,
+ void *payload) {
+ return(xmlHashUpdateInternal(hash, key, key2, key3, payload, NULL, 0));
+}
+
/**
* xmlHashAddEntry:
* @hash: hash table
@@ -615,11 +672,21 @@ xmlHashDefaultDeallocator(void *entry, const xmlChar *key ATTRIBUTE_UNUSED) {
* can't be distinguished from out-of-memory errors, so this function
* should be used with care.
*
+ * NOTE: This function doesn't allow to distinguish malloc failures from
+ * existing entries. Use xmlHashAdd instead.
+ *
* Returns 0 on success and -1 in case of error.
*/
int
xmlHashAddEntry(xmlHashTablePtr hash, const xmlChar *key, void *payload) {
- return(xmlHashUpdateInternal(hash, key, NULL, NULL, payload, NULL, 0));
+ int res = xmlHashUpdateInternal(hash, key, NULL, NULL, payload, NULL, 0);
+
+ if (res == 0)
+ res = -1;
+ else if (res == 1)
+ res = 0;
+
+ return(res);
}
/**
@@ -638,7 +705,14 @@ xmlHashAddEntry(xmlHashTablePtr hash, const xmlChar *key, void *payload) {
int
xmlHashAddEntry2(xmlHashTablePtr hash, const xmlChar *key,
const xmlChar *key2, void *payload) {
- return(xmlHashUpdateInternal(hash, key, key2, NULL, payload, NULL, 0));
+ int res = xmlHashUpdateInternal(hash, key, key2, NULL, payload, NULL, 0);
+
+ if (res == 0)
+ res = -1;
+ else if (res == 1)
+ res = 0;
+
+ return(res);
}
/**
@@ -659,7 +733,14 @@ int
xmlHashAddEntry3(xmlHashTablePtr hash, const xmlChar *key,
const xmlChar *key2, const xmlChar *key3,
void *payload) {
- return(xmlHashUpdateInternal(hash, key, key2, key3, payload, NULL, 0));
+ int res = xmlHashUpdateInternal(hash, key, key2, key3, payload, NULL, 0);
+
+ if (res == 0)
+ res = -1;
+ else if (res == 1)
+ res = 0;
+
+ return(res);
}
/**
@@ -677,8 +758,13 @@ xmlHashAddEntry3(xmlHashTablePtr hash, const xmlChar *key,
int
xmlHashUpdateEntry(xmlHashTablePtr hash, const xmlChar *key,
void *payload, xmlHashDeallocator dealloc) {
- return(xmlHashUpdateInternal(hash, key, NULL, NULL, payload,
- dealloc, 1));
+ int res = xmlHashUpdateInternal(hash, key, NULL, NULL, payload,
+ dealloc, 1);
+
+ if (res == 1)
+ res = 0;
+
+ return(res);
}
/**
@@ -699,8 +785,13 @@ int
xmlHashUpdateEntry2(xmlHashTablePtr hash, const xmlChar *key,
const xmlChar *key2, void *payload,
xmlHashDeallocator dealloc) {
- return(xmlHashUpdateInternal(hash, key, key2, NULL, payload,
- dealloc, 1));
+ int res = xmlHashUpdateInternal(hash, key, key2, NULL, payload,
+ dealloc, 1);
+
+ if (res == 1)
+ res = 0;
+
+ return(res);
}
/**
@@ -722,8 +813,13 @@ int
xmlHashUpdateEntry3(xmlHashTablePtr hash, const xmlChar *key,
const xmlChar *key2, const xmlChar *key3,
void *payload, xmlHashDeallocator dealloc) {
- return(xmlHashUpdateInternal(hash, key, key2, key3, payload,
- dealloc, 1));
+ int res = xmlHashUpdateInternal(hash, key, key2, key3, payload,
+ dealloc, 1);
+
+ if (res == 1)
+ res = 0;
+
+ return(res);
}
/**
@@ -1037,21 +1133,25 @@ xmlHashScanFull3(xmlHashTablePtr hash, const xmlChar *key,
}
}
-/**
- * xmlHashCopy:
+/*
+ * xmlHashCopySafe:
* @hash: hash table
- * @copy: copier function for items in the hash
+ * @copyFunc: copier function for items in the hash
+ * @deallocFunc: deallocation function in case of errors
+ *
+ * Copy the hash table using @copyFunc to copy payloads.
*
- * Copy the hash @table using @copy to copy payloads.
+ * Available since 2.13.0.
*
* Returns the new table or NULL if a memory allocation failed.
*/
xmlHashTablePtr
-xmlHashCopy(xmlHashTablePtr hash, xmlHashCopier copy) {
+xmlHashCopySafe(xmlHashTablePtr hash, xmlHashCopier copyFunc,
+ xmlHashDeallocator deallocFunc) {
const xmlHashEntry *entry, *end;
xmlHashTablePtr ret;
- if ((hash == NULL) || (copy == NULL))
+ if ((hash == NULL) || (copyFunc == NULL))
return(NULL);
ret = xmlHashCreate(hash->size);
@@ -1064,12 +1164,42 @@ xmlHashCopy(xmlHashTablePtr hash, xmlHashCopier copy) {
end = &hash->table[hash->size];
for (entry = hash->table; entry < end; entry++) {
- if (entry->hashValue != 0)
- xmlHashAddEntry3(ret, entry->key, entry->key2, entry->key3,
- copy(entry->payload, entry->key));
+ if (entry->hashValue != 0) {
+ void *copy;
+
+ copy = copyFunc(entry->payload, entry->key);
+ if (copy == NULL)
+ goto error;
+ if (xmlHashAdd3(ret, entry->key, entry->key2, entry->key3,
+ copy) <= 0) {
+ if (deallocFunc != NULL)
+ deallocFunc(copy, entry->key);
+ goto error;
+ }
+ }
}
return(ret);
+
+error:
+ xmlHashFree(ret, deallocFunc);
+ return(NULL);
+}
+
+/*
+ * xmlHashCopy:
+ * @hash: hash table
+ * @copy: copier function for items in the hash
+ *
+ * DEPRECATED: Leaks memory in error case.
+ *
+ * Copy the hash table using @copy to copy payloads.
+ *
+ * Returns the new table or NULL if a memory allocation failed.
+ */
+xmlHashTablePtr
+xmlHashCopy(xmlHashTablePtr hash, xmlHashCopier copy) {
+ return(xmlHashCopySafe(hash, copy, NULL));
}
/**
diff --git a/include/libxml/HTMLparser.h b/include/libxml/HTMLparser.h
index e16d774..7be3d2b 100644
--- a/include/libxml/HTMLparser.h
+++ b/include/libxml/HTMLparser.h
@@ -80,22 +80,17 @@ struct _htmlEntityDesc {
const char *desc; /* the description */
};
-/** DOC_DISABLE */
#ifdef LIBXML_SAX1_ENABLED
- #define XML_GLOBALS_HTML \
- XML_OP(htmlDefaultSAXHandler, xmlSAXHandlerV1, XML_DEPRECATED)
-#else
- #define XML_GLOBALS_HTML
-#endif
-#define XML_OP XML_DECLARE_GLOBAL
-XML_GLOBALS_HTML
-#undef XML_OP
+XML_DEPRECATED
+XMLPUBVAR const xmlSAXHandlerV1 htmlDefaultSAXHandler;
-#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION)
- #define htmlDefaultSAXHandler XML_GLOBAL_MACRO(htmlDefaultSAXHandler)
+#ifdef LIBXML_THREAD_ENABLED
+XML_DEPRECATED
+XMLPUBFUN const xmlSAXHandlerV1 *__htmlDefaultSAXHandler(void);
#endif
-/** DOC_ENABLE */
+
+#endif /* LIBXML_SAX1_ENABLED */
/*
* There is only few public functions.
@@ -173,6 +168,7 @@ XMLPUBFUN int
int *inlen, int quoteChar);
XMLPUBFUN int
htmlIsScriptAttribute(const xmlChar *name);
+XML_DEPRECATED
XMLPUBFUN int
htmlHandleOmittedElem(int val);
@@ -251,6 +247,9 @@ XMLPUBFUN htmlDocPtr
const char *URL,
const char *encoding,
int options);
+XMLPUBFUN htmlDocPtr
+ htmlCtxtParseDocument (htmlParserCtxtPtr ctxt,
+ xmlParserInputPtr input);
XMLPUBFUN htmlDocPtr
htmlCtxtReadDoc (xmlParserCtxtPtr ctxt,
const xmlChar *cur,
@@ -300,7 +299,7 @@ typedef enum {
XMLPUBFUN htmlStatus htmlAttrAllowed(const htmlElemDesc*, const xmlChar*, int) ;
XMLPUBFUN int htmlElementAllowedHere(const htmlElemDesc*, const xmlChar*) ;
XMLPUBFUN htmlStatus htmlElementStatusHere(const htmlElemDesc*, const htmlElemDesc*) ;
-XMLPUBFUN htmlStatus htmlNodeStatus(const htmlNodePtr, int) ;
+XMLPUBFUN htmlStatus htmlNodeStatus(htmlNodePtr, int) ;
/**
* htmlDefaultSubelement:
* @elt: HTML element
@@ -333,11 +332,5 @@ XMLPUBFUN htmlStatus htmlNodeStatus(const htmlNodePtr, int) ;
}
#endif
-#else /* LIBXML_HTML_ENABLED */
-
-/** DOC_DISABLE */
-#define XML_GLOBALS_HTML
-/** DOC_ENABLE */
-
#endif /* LIBXML_HTML_ENABLED */
#endif /* __HTML_PARSER_H__ */
diff --git a/include/libxml/c14n.h b/include/libxml/c14n.h
index f9bdf9b..8ccd1ce 100644
--- a/include/libxml/c14n.h
+++ b/include/libxml/c14n.h
@@ -39,18 +39,7 @@ extern "C" {
* a) default attributes (if any) are added to all nodes
* b) all character and parsed entity references are resolved
* In order to achieve this in libxml2 the document MUST be loaded with
- * following global settings:
- *
- * xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
- * xmlSubstituteEntitiesDefault(1);
- *
- * or corresponding parser context setting:
- * xmlParserCtxtPtr ctxt;
- *
- * ...
- * ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
- * ctxt->replaceEntities = 1;
- * ...
+ * following options: XML_PARSE_DTDATTR | XML_PARSE_NOENT
*/
/*
diff --git a/include/libxml/debugXML.h b/include/libxml/debugXML.h
index 8274687..1332dd7 100644
--- a/include/libxml/debugXML.h
+++ b/include/libxml/debugXML.h
@@ -203,7 +203,7 @@ XMLPUBFUN int
*/
XMLPUBFUN void
xmlShell (xmlDocPtr doc,
- char *filename,
+ const char *filename,
xmlShellReadlineFunc input,
FILE *output);
diff --git a/include/libxml/encoding.h b/include/libxml/encoding.h
index 8594cff..599a03e 100644
--- a/include/libxml/encoding.h
+++ b/include/libxml/encoding.h
@@ -162,6 +162,13 @@ XMLPUBFUN void
xmlCleanupCharEncodingHandlers (void);
XMLPUBFUN void
xmlRegisterCharEncodingHandler (xmlCharEncodingHandlerPtr handler);
+XMLPUBFUN int
+ xmlLookupCharEncodingHandler (xmlCharEncoding enc,
+ xmlCharEncodingHandlerPtr *out);
+XMLPUBFUN int
+ xmlOpenCharEncodingHandler (const char *name,
+ int output,
+ xmlCharEncodingHandlerPtr *out);
XMLPUBFUN xmlCharEncodingHandlerPtr
xmlGetCharEncodingHandler (xmlCharEncoding enc);
XMLPUBFUN xmlCharEncodingHandlerPtr
@@ -195,7 +202,9 @@ XMLPUBFUN xmlCharEncoding
xmlDetectCharEncoding (const unsigned char *in,
int len);
+/** DOC_DISABLE */
struct _xmlBuffer;
+/** DOC_ENABLE */
XMLPUBFUN int
xmlCharEncOutFunc (xmlCharEncodingHandler *handler,
struct _xmlBuffer *out,
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
index f679375..96029ba 100644
--- a/include/libxml/entities.h
+++ b/include/libxml/entities.h
@@ -12,9 +12,7 @@
#define __XML_ENTITIES_H__
#include
-#define XML_TREE_INTERNALS
#include
-#undef XML_TREE_INTERNALS
#ifdef __cplusplus
extern "C" {
@@ -57,7 +55,7 @@ struct _xmlEntity {
struct _xmlEntity *nexte; /* unused */
const xmlChar *URI; /* the full URI as computed */
- int owner; /* does the entity own the childrens */
+ int owner; /* unused */
int flags; /* various flags */
unsigned long expandedSize; /* expanded size */
};
@@ -89,6 +87,15 @@ XMLPUBFUN xmlEntityPtr
const xmlChar *content);
XMLPUBFUN void
xmlFreeEntity (xmlEntityPtr entity);
+XMLPUBFUN int
+ xmlAddEntity (xmlDocPtr doc,
+ int extSubset,
+ const xmlChar *name,
+ int type,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID,
+ const xmlChar *content,
+ xmlEntityPtr *out);
XMLPUBFUN xmlEntityPtr
xmlAddDocEntity (xmlDocPtr doc,
const xmlChar *name,
diff --git a/include/libxml/hash.h b/include/libxml/hash.h
index f4af09e..135b696 100644
--- a/include/libxml/hash.h
+++ b/include/libxml/hash.h
@@ -109,6 +109,10 @@ XMLPUBFUN void
/*
* Add a new entry to the hash table.
*/
+XMLPUBFUN int
+ xmlHashAdd (xmlHashTablePtr hash,
+ const xmlChar *name,
+ void *userdata);
XMLPUBFUN int
xmlHashAddEntry (xmlHashTablePtr hash,
const xmlChar *name,
@@ -118,6 +122,11 @@ XMLPUBFUN int
const xmlChar *name,
void *userdata,
xmlHashDeallocator dealloc);
+XMLPUBFUN int
+ xmlHashAdd2 (xmlHashTablePtr hash,
+ const xmlChar *name,
+ const xmlChar *name2,
+ void *userdata);
XMLPUBFUN int
xmlHashAddEntry2 (xmlHashTablePtr hash,
const xmlChar *name,
@@ -129,6 +138,12 @@ XMLPUBFUN int
const xmlChar *name2,
void *userdata,
xmlHashDeallocator dealloc);
+XMLPUBFUN int
+ xmlHashAdd3 (xmlHashTablePtr hash,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ void *userdata);
XMLPUBFUN int
xmlHashAddEntry3 (xmlHashTablePtr hash,
const xmlChar *name,
@@ -199,6 +214,10 @@ XMLPUBFUN void *
/*
* Helpers.
*/
+XMLPUBFUN xmlHashTablePtr
+ xmlHashCopySafe (xmlHashTablePtr hash,
+ xmlHashCopier copy,
+ xmlHashDeallocator dealloc);
XMLPUBFUN xmlHashTablePtr
xmlHashCopy (xmlHashTablePtr hash,
xmlHashCopier copy);
diff --git a/include/libxml/list.h b/include/libxml/list.h
index 5eab8f5..1fa76af 100644
--- a/include/libxml/list.h
+++ b/include/libxml/list.h
@@ -119,10 +119,10 @@ XMLPUBFUN void
xmlListMerge (xmlListPtr l1,
xmlListPtr l2);
XMLPUBFUN xmlListPtr
- xmlListDup (const xmlListPtr old);
+ xmlListDup (xmlListPtr old);
XMLPUBFUN int
xmlListCopy (xmlListPtr cur,
- const xmlListPtr old);
+ xmlListPtr old);
/* Link operators */
XMLPUBFUN void *
xmlLinkGetData (xmlLinkPtr lk);
diff --git a/include/libxml/nanohttp.h b/include/libxml/nanohttp.h
index 3b5e037..c70d1c2 100644
--- a/include/libxml/nanohttp.h
+++ b/include/libxml/nanohttp.h
@@ -18,16 +18,21 @@
#ifdef __cplusplus
extern "C" {
#endif
+XML_DEPRECATED
XMLPUBFUN void
xmlNanoHTTPInit (void);
+XML_DEPRECATED
XMLPUBFUN void
xmlNanoHTTPCleanup (void);
+XML_DEPRECATED
XMLPUBFUN void
xmlNanoHTTPScanProxy (const char *URL);
+XML_DEPRECATED
XMLPUBFUN int
xmlNanoHTTPFetch (const char *URL,
const char *filename,
char **contentType);
+XML_DEPRECATED
XMLPUBFUN void *
xmlNanoHTTPMethod (const char *URL,
const char *method,
@@ -35,6 +40,7 @@ XMLPUBFUN void *
char **contentType,
const char *headers,
int ilen);
+XML_DEPRECATED
XMLPUBFUN void *
xmlNanoHTTPMethodRedir (const char *URL,
const char *method,
@@ -43,34 +49,45 @@ XMLPUBFUN void *
char **redir,
const char *headers,
int ilen);
+XML_DEPRECATED
XMLPUBFUN void *
xmlNanoHTTPOpen (const char *URL,
char **contentType);
+XML_DEPRECATED
XMLPUBFUN void *
xmlNanoHTTPOpenRedir (const char *URL,
char **contentType,
char **redir);
+XML_DEPRECATED
XMLPUBFUN int
xmlNanoHTTPReturnCode (void *ctx);
+XML_DEPRECATED
XMLPUBFUN const char *
xmlNanoHTTPAuthHeader (void *ctx);
+XML_DEPRECATED
XMLPUBFUN const char *
xmlNanoHTTPRedir (void *ctx);
+XML_DEPRECATED
XMLPUBFUN int
xmlNanoHTTPContentLength( void * ctx );
+XML_DEPRECATED
XMLPUBFUN const char *
xmlNanoHTTPEncoding (void *ctx);
+XML_DEPRECATED
XMLPUBFUN const char *
xmlNanoHTTPMimeType (void *ctx);
+XML_DEPRECATED
XMLPUBFUN int
xmlNanoHTTPRead (void *ctx,
void *dest,
int len);
#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
XMLPUBFUN int
xmlNanoHTTPSave (void *ctxt,
const char *filename);
#endif /* LIBXML_OUTPUT_ENABLED */
+XML_DEPRECATED
XMLPUBFUN void
xmlNanoHTTPClose (void *ctx);
#ifdef __cplusplus
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index 87aacef..86dd54f 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -11,9 +11,7 @@
#define __XML_PARSER_H__
#include
-#define XML_TREE_INTERNALS
#include
-#undef XML_TREE_INTERNALS
#include
#include
#include
@@ -62,11 +60,11 @@ struct _xmlParserInput {
xmlParserInputBufferPtr buf; /* UTF-8 encoded buffer */
const char *filename; /* The file analyzed, if any */
- const char *directory; /* the directory/base of the file */
+ const char *directory; /* unused */
const xmlChar *base; /* Base of the array to parse */
const xmlChar *cur; /* Current char being parsed */
const xmlChar *end; /* end of the array to parse */
- int length; /* length if known */
+ int length; /* unused */
int line; /* Current line */
int col; /* Current column */
unsigned long consumed; /* How many xmlChars already consumed */
@@ -75,7 +73,7 @@ struct _xmlParserInput {
const xmlChar *version; /* the version string for entity */
int flags; /* Flags */
int id; /* an unique identifier for the entity */
- unsigned long parentConsumed; /* consumed bytes from parents */
+ unsigned long parentConsumed; /* unused */
xmlEntityPtr entity; /* entity, if any */
};
@@ -134,30 +132,14 @@ typedef enum {
XML_PARSER_XML_DECL /* before XML decl (but after BOM) */
} xmlParserInputState;
-/**
- * XML_DETECT_IDS:
- *
- * Bit in the loadsubset context field to tell to do ID/REFs lookups.
- * Use it to initialize xmlLoadExtDtdDefaultValue.
+/** DOC_DISABLE */
+/*
+ * Internal bits in the 'loadsubset' context member
*/
#define XML_DETECT_IDS 2
-
-/**
- * XML_COMPLETE_ATTRS:
- *
- * Bit in the loadsubset context field to tell to do complete the
- * elements attributes lists with the ones defaulted from the DTDs.
- * Use it to initialize xmlLoadExtDtdDefaultValue.
- */
#define XML_COMPLETE_ATTRS 4
-
-/**
- * XML_SKIP_IDS:
- *
- * Bit in the loadsubset context field to tell to not do ID/REFs registration.
- * Used to initialize xmlLoadExtDtdDefaultValue in some special cases.
- */
#define XML_SKIP_IDS 8
+/** DOC_ENABLE */
/**
* xmlParserMode:
@@ -222,16 +204,16 @@ struct _xmlParserCtxt {
int hasExternalSubset; /* reference and external subset */
int hasPErefs; /* the internal subset has PE refs */
- int external; /* are we parsing an external entity */
+ int external; /* unused */
int valid; /* is the document valid */
int validate; /* shall we try to validate ? */
xmlValidCtxt vctxt; /* The validity context */
- xmlParserInputState instate; /* current type of input */
- int token; /* next char look-ahead */
+ xmlParserInputState instate; /* push parser state */
+ int token; /* unused */
- char *directory; /* the data directory */
+ char *directory; /* unused */
/* Node name stack */
const xmlChar *name; /* Current parsed Node */
@@ -255,7 +237,7 @@ struct _xmlParserCtxt {
int * spaceTab; /* array of space infos */
int depth; /* to prevent entity substitution loops */
- xmlParserInputPtr entity; /* used to check entities boundaries */
+ xmlParserInputPtr entity; /* unused */
int charset; /* unused */
int nodelen; /* Those two fields are there to */
int nodemem; /* Speed up large node parsing */
@@ -266,11 +248,11 @@ struct _xmlParserCtxt {
int linenumbers; /* set line number in element content */
void *catalogs; /* document's own catalog */
int recovery; /* run in recovery mode */
- int progressive; /* is this a progressive parsing */
+ int progressive; /* unused */
xmlDictPtr dict; /* dictionary for the parser */
const xmlChar * *atts; /* array for the attributes callbacks */
int maxatts; /* the size of the array */
- int docdict; /* use strings from dict to build tree */
+ int docdict; /* unused */
/*
* pre-interned strings
@@ -308,7 +290,7 @@ struct _xmlParserCtxt {
xmlError lastError;
xmlParserMode parseMode; /* the parser mode */
unsigned long nbentities; /* unused */
- unsigned long sizeentities; /* size of parsed entities */
+ unsigned long sizeentities; /* size of external entities */
/* for use by HTML non-recursive parser */
xmlParserNodeInfo *nodeInfo; /* Current NodeInfo */
@@ -327,6 +309,9 @@ struct _xmlParserCtxt {
xmlParserNsData *nsdb; /* namespace database */
unsigned attrHashMax; /* allocated size */
xmlAttrHashBucket *attrHash; /* atttribute hash table */
+
+ xmlStructuredErrorFunc errorHandler;
+ void *errorCtxt;
};
/**
@@ -843,21 +828,39 @@ typedef xmlParserInputPtr (*xmlExternalEntityLoader) (const char *URL,
*/
XMLPUBVAR const char *const xmlParserVersion;
+XML_DEPRECATED
+XMLPUBVAR const int oldXMLWDcompatibility;
+XML_DEPRECATED
+XMLPUBVAR const int xmlParserDebugEntities;
+XML_DEPRECATED
+XMLPUBVAR const xmlSAXLocator xmlDefaultSAXLocator;
+#ifdef LIBXML_SAX1_ENABLED
+XML_DEPRECATED
+XMLPUBVAR const xmlSAXHandlerV1 xmlDefaultSAXHandler;
+#endif
+
#ifdef LIBXML_THREAD_ENABLED
/* backward compatibility */
XMLPUBFUN const char *const *__xmlParserVersion(void);
+XML_DEPRECATED
+XMLPUBFUN const int *__oldXMLWDcompatibility(void);
+XML_DEPRECATED
+XMLPUBFUN const int *__xmlParserDebugEntities(void);
+XML_DEPRECATED
+XMLPUBFUN const xmlSAXLocator *__xmlDefaultSAXLocator(void);
+#ifdef LIBXML_SAX1_ENABLED
+XML_DEPRECATED
+XMLPUBFUN const xmlSAXHandlerV1 *__xmlDefaultSAXHandler(void);
+#endif
#endif
/** DOC_DISABLE */
#define XML_GLOBALS_PARSER_CORE \
- XML_OP(oldXMLWDcompatibility, int, XML_DEPRECATED) \
- XML_OP(xmlDefaultSAXLocator, xmlSAXLocator, XML_DEPRECATED) \
XML_OP(xmlDoValidityCheckingDefaultValue, int, XML_DEPRECATED) \
XML_OP(xmlGetWarningsDefaultValue, int, XML_DEPRECATED) \
XML_OP(xmlKeepBlanksDefaultValue, int, XML_DEPRECATED) \
XML_OP(xmlLineNumbersDefaultValue, int, XML_DEPRECATED) \
XML_OP(xmlLoadExtDtdDefaultValue, int, XML_DEPRECATED) \
- XML_OP(xmlParserDebugEntities, int, XML_DEPRECATED) \
XML_OP(xmlPedanticParserDefaultValue, int, XML_DEPRECATED) \
XML_OP(xmlSubstituteEntitiesDefaultValue, int, XML_DEPRECATED)
@@ -870,26 +873,15 @@ XMLPUBFUN const char *const *__xmlParserVersion(void);
#define XML_GLOBALS_PARSER_OUTPUT
#endif
-#ifdef LIBXML_SAX1_ENABLED
- #define XML_GLOBALS_PARSER_SAX1 \
- XML_OP(xmlDefaultSAXHandler, xmlSAXHandlerV1, XML_DEPRECATED)
-#else
- #define XML_GLOBALS_PARSER_SAX1
-#endif
-
#define XML_GLOBALS_PARSER \
XML_GLOBALS_PARSER_CORE \
- XML_GLOBALS_PARSER_OUTPUT \
- XML_GLOBALS_PARSER_SAX1
+ XML_GLOBALS_PARSER_OUTPUT
#define XML_OP XML_DECLARE_GLOBAL
XML_GLOBALS_PARSER
#undef XML_OP
#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION)
- #define oldXMLWDcompatibility XML_GLOBAL_MACRO(oldXMLWDcompatibility)
- #define xmlDefaultSAXHandler XML_GLOBAL_MACRO(xmlDefaultSAXHandler)
- #define xmlDefaultSAXLocator XML_GLOBAL_MACRO(xmlDefaultSAXLocator)
#define xmlDoValidityCheckingDefaultValue \
XML_GLOBAL_MACRO(xmlDoValidityCheckingDefaultValue)
#define xmlGetWarningsDefaultValue \
@@ -898,7 +890,6 @@ XML_GLOBALS_PARSER
#define xmlLineNumbersDefaultValue \
XML_GLOBAL_MACRO(xmlLineNumbersDefaultValue)
#define xmlLoadExtDtdDefaultValue XML_GLOBAL_MACRO(xmlLoadExtDtdDefaultValue)
- #define xmlParserDebugEntities XML_GLOBAL_MACRO(xmlParserDebugEntities)
#define xmlPedanticParserDefaultValue \
XML_GLOBAL_MACRO(xmlPedanticParserDefaultValue)
#define xmlSubstituteEntitiesDefaultValue \
@@ -1185,18 +1176,18 @@ XMLPUBFUN xmlParserInputPtr
* Node infos.
*/
XMLPUBFUN const xmlParserNodeInfo*
- xmlParserFindNodeInfo (const xmlParserCtxtPtr ctxt,
- const xmlNodePtr node);
+ xmlParserFindNodeInfo (xmlParserCtxtPtr ctxt,
+ xmlNodePtr node);
XMLPUBFUN void
xmlInitNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
XMLPUBFUN void
xmlClearNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
XMLPUBFUN unsigned long
- xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
- const xmlNodePtr node);
+ xmlParserFindNodeInfoIndex(xmlParserNodeInfoSeqPtr seq,
+ xmlNodePtr node);
XMLPUBFUN void
xmlParserAddNodeInfo (xmlParserCtxtPtr ctxt,
- const xmlParserNodeInfoPtr info);
+ xmlParserNodeInfoPtr info);
/*
* External entities handling actually implemented in xmlIO.
@@ -1251,7 +1242,8 @@ typedef enum {
XML_PARSE_HUGE = 1<<19,/* relax any hardcoded limit from the parser */
XML_PARSE_OLDSAX = 1<<20,/* parse using SAX2 interface before 2.7.0 */
XML_PARSE_IGNORE_ENC= 1<<21,/* ignore internal document encoding hint */
- XML_PARSE_BIG_LINES = 1<<22 /* Store big lines numbers in text PSVI field */
+ XML_PARSE_BIG_LINES = 1<<22,/* Store big lines numbers in text PSVI field */
+ XML_PARSE_NO_XXE = 1<<23 /* disable loading of external content */
} xmlParserOption;
XMLPUBFUN void
@@ -1262,9 +1254,16 @@ XMLPUBFUN int
int size,
const char *filename,
const char *encoding);
+XMLPUBFUN int
+ xmlCtxtSetOptions (xmlParserCtxtPtr ctxt,
+ int options);
XMLPUBFUN int
xmlCtxtUseOptions (xmlParserCtxtPtr ctxt,
int options);
+XMLPUBFUN void
+ xmlCtxtSetErrorHandler (xmlParserCtxtPtr ctxt,
+ xmlStructuredErrorFunc handler,
+ void *data);
XMLPUBFUN void
xmlCtxtSetMaxAmplification(xmlParserCtxtPtr ctxt,
unsigned maxAmpl);
@@ -1295,6 +1294,9 @@ XMLPUBFUN xmlDocPtr
const char *URL,
const char *encoding,
int options);
+XMLPUBFUN xmlDocPtr
+ xmlCtxtParseDocument (xmlParserCtxtPtr ctxt,
+ xmlParserInputPtr input);
XMLPUBFUN xmlDocPtr
xmlCtxtReadDoc (xmlParserCtxtPtr ctxt,
const xmlChar *cur,
@@ -1368,7 +1370,7 @@ typedef enum {
XML_WITH_MODULES = 27,
XML_WITH_DEBUG = 28,
XML_WITH_DEBUG_MEM = 29,
- XML_WITH_DEBUG_RUN = 30,
+ XML_WITH_DEBUG_RUN = 30, /* unused */
XML_WITH_ZLIB = 31,
XML_WITH_ICU = 32,
XML_WITH_LZMA = 33,
diff --git a/include/libxml/parserInternals.h b/include/libxml/parserInternals.h
index 073ddf3..a79bb62 100644
--- a/include/libxml/parserInternals.h
+++ b/include/libxml/parserInternals.h
@@ -25,11 +25,14 @@ extern "C" {
/**
* xmlParserMaxDepth:
*
+ * DEPRECATED: has no effect
+ *
* arbitrary depth limit for the XML documents that we allow to
* process. This is not a limitation of the parser but a safety
* boundary feature, use XML_PARSE_HUGE option to override it.
*/
-XMLPUBVAR unsigned int xmlParserMaxDepth;
+XML_DEPRECATED
+XMLPUBVAR const unsigned int xmlParserMaxDepth;
/**
* XML_MAX_TEXT_LENGTH:
@@ -313,9 +316,14 @@ XMLPUBFUN xmlParserCtxtPtr
xmlCreateEntityParserCtxt(const xmlChar *URL,
const xmlChar *ID,
const xmlChar *base);
+XMLPUBFUN void
+ xmlCtxtErrMemory (xmlParserCtxtPtr ctxt);
XMLPUBFUN int
xmlSwitchEncoding (xmlParserCtxtPtr ctxt,
xmlCharEncoding enc);
+XMLPUBFUN int
+ xmlSwitchEncodingName (xmlParserCtxtPtr ctxt,
+ const char *encoding);
XMLPUBFUN int
xmlSwitchToEncoding (xmlParserCtxtPtr ctxt,
xmlCharEncodingHandlerPtr handler);
diff --git a/include/libxml/pattern.h b/include/libxml/pattern.h
index 72bf239..947f090 100644
--- a/include/libxml/pattern.h
+++ b/include/libxml/pattern.h
@@ -54,6 +54,12 @@ XMLPUBFUN xmlPatternPtr
xmlDict *dict,
int flags,
const xmlChar **namespaces);
+XMLPUBFUN int
+ xmlPatternCompileSafe (const xmlChar *pattern,
+ xmlDict *dict,
+ int flags,
+ const xmlChar **namespaces,
+ xmlPatternPtr *patternOut);
XMLPUBFUN int
xmlPatternMatch (xmlPatternPtr comp,
xmlNodePtr node);
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index a90a174..19bb126 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -9,15 +9,6 @@
* Author: Daniel Veillard
*/
-#ifndef XML_TREE_INTERNALS
-
-/*
- * Emulate circular dependency for backward compatibility
- */
-#include
-
-#else /* XML_TREE_INTERNALS */
-
#ifndef __XML_TREE_H__
#define __XML_TREE_H__
@@ -173,13 +164,13 @@ typedef enum {
XML_TEXT_NODE= 3,
XML_CDATA_SECTION_NODE= 4,
XML_ENTITY_REF_NODE= 5,
- XML_ENTITY_NODE= 6,
+ XML_ENTITY_NODE= 6, /* unused */
XML_PI_NODE= 7,
XML_COMMENT_NODE= 8,
XML_DOCUMENT_NODE= 9,
- XML_DOCUMENT_TYPE_NODE= 10,
+ XML_DOCUMENT_TYPE_NODE= 10, /* unused */
XML_DOCUMENT_FRAG_NODE= 11,
- XML_NOTATION_NODE= 12,
+ XML_NOTATION_NODE= 12, /* unused */
XML_HTML_DOCUMENT_NODE= 13,
XML_DTD_NODE= 14,
XML_ELEMENT_DECL= 15,
@@ -449,6 +440,7 @@ struct _xmlAttr {
xmlNs *ns; /* pointer to the associated namespace */
xmlAttributeType atype; /* the attribute type if validating */
void *psvi; /* for type/PSVI information */
+ struct _xmlID *id; /* the ID struct */
};
/**
@@ -1011,10 +1003,10 @@ XMLPUBFUN void
xmlFreeNodeList (xmlNodePtr cur);
XMLPUBFUN void
xmlFreeNode (xmlNodePtr cur);
-XMLPUBFUN void
+XMLPUBFUN int
xmlSetTreeDoc (xmlNodePtr tree,
xmlDocPtr doc);
-XMLPUBFUN void
+XMLPUBFUN int
xmlSetListDoc (xmlNodePtr list,
xmlDocPtr doc);
/*
@@ -1030,6 +1022,10 @@ XMLPUBFUN xmlNsPtr
const xmlChar *href);
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || \
defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN int
+ xmlGetNsListSafe (const xmlDoc *doc,
+ const xmlNode *node,
+ xmlNsPtr **out);
XMLPUBFUN xmlNsPtr *
xmlGetNsList (const xmlDoc *doc,
const xmlNode *node);
@@ -1059,6 +1055,11 @@ XMLPUBFUN xmlAttrPtr
const xmlChar *value);
#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || \
defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED) */
+XMLPUBFUN int
+ xmlNodeGetAttrValue (const xmlNode *node,
+ const xmlChar *name,
+ const xmlChar *nsUri,
+ xmlChar **out);
XMLPUBFUN xmlChar *
xmlGetNoNsProp (const xmlNode *node,
const xmlChar *name);
@@ -1093,19 +1094,19 @@ XMLPUBFUN xmlChar *
const xmlNode *list,
int inLine);
#endif /* LIBXML_TREE_ENABLED */
-XMLPUBFUN void
+XMLPUBFUN int
xmlNodeSetContent (xmlNodePtr cur,
const xmlChar *content);
#ifdef LIBXML_TREE_ENABLED
-XMLPUBFUN void
+XMLPUBFUN int
xmlNodeSetContentLen (xmlNodePtr cur,
const xmlChar *content,
int len);
#endif /* LIBXML_TREE_ENABLED */
-XMLPUBFUN void
+XMLPUBFUN int
xmlNodeAddContent (xmlNodePtr cur,
const xmlChar *content);
-XMLPUBFUN void
+XMLPUBFUN int
xmlNodeAddContentLen (xmlNodePtr cur,
const xmlChar *content,
int len);
@@ -1124,18 +1125,22 @@ XMLPUBFUN xmlChar *
XMLPUBFUN int
xmlNodeGetSpacePreserve (const xmlNode *cur);
#ifdef LIBXML_TREE_ENABLED
-XMLPUBFUN void
+XMLPUBFUN int
xmlNodeSetLang (xmlNodePtr cur,
const xmlChar *lang);
-XMLPUBFUN void
+XMLPUBFUN int
xmlNodeSetSpacePreserve (xmlNodePtr cur,
int val);
#endif /* LIBXML_TREE_ENABLED */
+XMLPUBFUN int
+ xmlNodeGetBaseSafe (const xmlDoc *doc,
+ const xmlNode *cur,
+ xmlChar **baseOut);
XMLPUBFUN xmlChar *
xmlNodeGetBase (const xmlDoc *doc,
const xmlNode *cur);
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
-XMLPUBFUN void
+XMLPUBFUN int
xmlNodeSetBase (xmlNodePtr cur,
const xmlChar *uri);
#endif
@@ -1283,8 +1288,10 @@ XMLPUBFUN int
XMLPUBFUN void
xmlSetDocCompressMode (xmlDocPtr doc,
int mode);
+XML_DEPRECATED
XMLPUBFUN int
xmlGetCompressMode (void);
+XML_DEPRECATED
XMLPUBFUN void
xmlSetCompressMode (int mode);
@@ -1338,12 +1345,16 @@ XMLPUBFUN xmlNodePtr
xmlPreviousElementSibling (xmlNodePtr node);
#endif
+XML_DEPRECATED
XMLPUBFUN xmlRegisterNodeFunc
xmlRegisterNodeDefault (xmlRegisterNodeFunc func);
+XML_DEPRECATED
XMLPUBFUN xmlDeregisterNodeFunc
xmlDeregisterNodeDefault (xmlDeregisterNodeFunc func);
+XML_DEPRECATED
XMLPUBFUN xmlRegisterNodeFunc
xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func);
+XML_DEPRECATED
XMLPUBFUN xmlDeregisterNodeFunc
xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func);
@@ -1358,5 +1369,3 @@ XML_DEPRECATED XMLPUBFUN int
#endif /* __XML_TREE_H__ */
-#endif /* XML_TREE_INTERNALS */
-
diff --git a/include/libxml/uri.h b/include/libxml/uri.h
index eb8631c..19980b7 100644
--- a/include/libxml/uri.h
+++ b/include/libxml/uri.h
@@ -52,14 +52,25 @@ struct _xmlURI {
*/
XMLPUBFUN xmlURIPtr
xmlCreateURI (void);
+XMLPUBFUN int
+ xmlBuildURISafe (const xmlChar *URI,
+ const xmlChar *base,
+ xmlChar **out);
XMLPUBFUN xmlChar *
xmlBuildURI (const xmlChar *URI,
const xmlChar *base);
+XMLPUBFUN int
+ xmlBuildRelativeURISafe (const xmlChar *URI,
+ const xmlChar *base,
+ xmlChar **out);
XMLPUBFUN xmlChar *
xmlBuildRelativeURI (const xmlChar *URI,
const xmlChar *base);
XMLPUBFUN xmlURIPtr
xmlParseURI (const char *str);
+XMLPUBFUN int
+ xmlParseURISafe (const char *str,
+ xmlURIPtr *uri);
XMLPUBFUN xmlURIPtr
xmlParseURIRaw (const char *str,
int raw);
diff --git a/include/libxml/valid.h b/include/libxml/valid.h
index 3e04b55..361e965 100644
--- a/include/libxml/valid.h
+++ b/include/libxml/valid.h
@@ -13,9 +13,7 @@
#include
#include
-#define XML_TREE_INTERNALS
#include
-#undef XML_TREE_INTERNALS
#include
#include
#include
@@ -150,9 +148,11 @@ XMLPUBFUN xmlNotationTablePtr
XMLPUBFUN void
xmlFreeNotationTable (xmlNotationTablePtr table);
#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
XMLPUBFUN void
xmlDumpNotationDecl (xmlBufferPtr buf,
xmlNotationPtr nota);
+/* XML_DEPRECATED, still used in lxml */
XMLPUBFUN void
xmlDumpNotationTable (xmlBufferPtr buf,
xmlNotationTablePtr table);
@@ -184,13 +184,12 @@ XMLPUBFUN void
xmlElementContentPtr content,
int englob);
#ifdef LIBXML_OUTPUT_ENABLED
-/* DEPRECATED */
+XML_DEPRECATED
XMLPUBFUN void
xmlSprintfElementContent(char *buf,
xmlElementContentPtr content,
int englob);
#endif /* LIBXML_OUTPUT_ENABLED */
-/* DEPRECATED */
/* Element */
XMLPUBFUN xmlElementPtr
@@ -206,9 +205,11 @@ XMLPUBFUN xmlElementTablePtr
XMLPUBFUN void
xmlFreeElementTable (xmlElementTablePtr table);
#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
XMLPUBFUN void
xmlDumpElementTable (xmlBufferPtr buf,
xmlElementTablePtr table);
+XML_DEPRECATED
XMLPUBFUN void
xmlDumpElementDecl (xmlBufferPtr buf,
xmlElementPtr elem);
@@ -242,15 +243,20 @@ XMLPUBFUN xmlAttributeTablePtr
XMLPUBFUN void
xmlFreeAttributeTable (xmlAttributeTablePtr table);
#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
XMLPUBFUN void
xmlDumpAttributeTable (xmlBufferPtr buf,
xmlAttributeTablePtr table);
+XML_DEPRECATED
XMLPUBFUN void
xmlDumpAttributeDecl (xmlBufferPtr buf,
xmlAttributePtr attr);
#endif /* LIBXML_OUTPUT_ENABLED */
/* IDs */
+XMLPUBFUN int
+ xmlAddIDSafe (xmlAttrPtr attr,
+ const xmlChar *value);
XMLPUBFUN xmlIDPtr
xmlAddID (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
@@ -303,31 +309,38 @@ XMLPUBFUN xmlValidCtxtPtr
XMLPUBFUN void
xmlFreeValidCtxt(xmlValidCtxtPtr);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateRoot (xmlValidCtxtPtr ctxt,
xmlDocPtr doc);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateElementDecl (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
xmlElementPtr elem);
+XML_DEPRECATED
XMLPUBFUN xmlChar *
xmlValidNormalizeAttributeValue(xmlDocPtr doc,
xmlNodePtr elem,
const xmlChar *name,
const xmlChar *value);
+XML_DEPRECATED
XMLPUBFUN xmlChar *
xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
xmlNodePtr elem,
const xmlChar *name,
const xmlChar *value);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
xmlAttributePtr attr);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateAttributeValue(xmlAttributeType type,
const xmlChar *value);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateNotationDecl (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
@@ -336,6 +349,7 @@ XMLPUBFUN int
xmlValidateDtd (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
xmlDtdPtr dtd);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateDtdFinal (xmlValidCtxtPtr ctxt,
xmlDocPtr doc);
@@ -346,16 +360,19 @@ XMLPUBFUN int
xmlValidateElement (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
xmlNodePtr elem);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateOneElement (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
xmlNodePtr elem);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
xmlNodePtr elem,
xmlAttrPtr attr,
const xmlChar *value);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateOneNamespace (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
@@ -363,12 +380,14 @@ XMLPUBFUN int
const xmlChar *prefix,
xmlNsPtr ns,
const xmlChar *value);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
xmlDocPtr doc);
#endif /* LIBXML_VALID_ENABLED */
#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+XML_DEPRECATED
XMLPUBFUN int
xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
@@ -424,19 +443,23 @@ XMLPUBFUN int
/*
* Validation based on the regexp support
*/
+XML_DEPRECATED
XMLPUBFUN int
xmlValidBuildContentModel(xmlValidCtxtPtr ctxt,
xmlElementPtr elem);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidatePushElement (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
xmlNodePtr elem,
const xmlChar *qname);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidatePushCData (xmlValidCtxtPtr ctxt,
const xmlChar *data,
int len);
+XML_DEPRECATED
XMLPUBFUN int
xmlValidatePopElement (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
diff --git a/include/libxml/xinclude.h b/include/libxml/xinclude.h
index e1d135b..6a67953 100644
--- a/include/libxml/xinclude.h
+++ b/include/libxml/xinclude.h
@@ -115,6 +115,12 @@ XMLPUBFUN xmlXIncludeCtxtPtr
XMLPUBFUN int
xmlXIncludeSetFlags (xmlXIncludeCtxtPtr ctxt,
int flags);
+XMLPUBFUN void
+ xmlXIncludeSetErrorHandler(xmlXIncludeCtxtPtr ctxt,
+ xmlStructuredErrorFunc handler,
+ void *data);
+XMLPUBFUN int
+ xmlXIncludeGetLastError (xmlXIncludeCtxtPtr ctxt);
XMLPUBFUN void
xmlXIncludeFreeContext (xmlXIncludeCtxtPtr ctxt);
XMLPUBFUN int
diff --git a/include/libxml/xmlIO.h b/include/libxml/xmlIO.h
index 2487be3..66eebd4 100644
--- a/include/libxml/xmlIO.h
+++ b/include/libxml/xmlIO.h
@@ -13,9 +13,7 @@
#include
#include
#include
-#define XML_TREE_INTERNALS
#include
-#undef XML_TREE_INTERNALS
#ifdef __cplusplus
extern "C" {
@@ -323,12 +321,14 @@ xmlOutputBufferPtr
#ifdef LIBXML_HTTP_ENABLED
/* This function only exists if HTTP support built into the library */
+XML_DEPRECATED
XMLPUBFUN void
xmlRegisterHTTPPostCallbacks (void );
#endif /* LIBXML_HTTP_ENABLED */
#endif /* LIBXML_OUTPUT_ENABLED */
+XML_DEPRECATED
XMLPUBFUN xmlParserInputPtr
xmlCheckHTTPInput (xmlParserCtxtPtr ctxt,
xmlParserInputPtr ret);
@@ -341,26 +341,28 @@ XMLPUBFUN xmlParserInputPtr
const char *ID,
xmlParserCtxtPtr ctxt);
-/*
- * xmlNormalizeWindowsPath is obsolete, don't use it.
- * Check xmlCanonicPath in uri.h for a better alternative.
- */
+XML_DEPRECATED
XMLPUBFUN xmlChar *
xmlNormalizeWindowsPath (const xmlChar *path);
+XML_DEPRECATED
XMLPUBFUN int
xmlCheckFilename (const char *path);
/**
* Default 'file://' protocol callbacks
*/
+XML_DEPRECATED
XMLPUBFUN int
xmlFileMatch (const char *filename);
+XML_DEPRECATED
XMLPUBFUN void *
xmlFileOpen (const char *filename);
+XML_DEPRECATED
XMLPUBFUN int
xmlFileRead (void * context,
char * buffer,
int len);
+XML_DEPRECATED
XMLPUBFUN int
xmlFileClose (void * context);
@@ -368,19 +370,24 @@ XMLPUBFUN int
* Default 'http://' protocol callbacks
*/
#ifdef LIBXML_HTTP_ENABLED
+XML_DEPRECATED
XMLPUBFUN int
xmlIOHTTPMatch (const char *filename);
+XML_DEPRECATED
XMLPUBFUN void *
xmlIOHTTPOpen (const char *filename);
#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
XMLPUBFUN void *
xmlIOHTTPOpenW (const char * post_uri,
int compression );
#endif /* LIBXML_OUTPUT_ENABLED */
+XML_DEPRECATED
XMLPUBFUN int
xmlIOHTTPRead (void * context,
char * buffer,
int len);
+XML_DEPRECATED
XMLPUBFUN int
xmlIOHTTPClose (void * context);
#endif /* LIBXML_HTTP_ENABLED */
@@ -389,14 +396,18 @@ XMLPUBFUN int
* Default 'ftp://' protocol callbacks
*/
#if defined(LIBXML_FTP_ENABLED)
+XML_DEPRECATED
XMLPUBFUN int
xmlIOFTPMatch (const char *filename);
+XML_DEPRECATED
XMLPUBFUN void *
xmlIOFTPOpen (const char *filename);
+XML_DEPRECATED
XMLPUBFUN int
xmlIOFTPRead (void * context,
char * buffer,
int len);
+XML_DEPRECATED
XMLPUBFUN int
xmlIOFTPClose (void * context);
#endif /* defined(LIBXML_FTP_ENABLED) */
@@ -407,9 +418,11 @@ XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
XMLPUBFUN xmlOutputBufferCreateFilenameFunc
xmlOutputBufferCreateFilenameDefault(
xmlOutputBufferCreateFilenameFunc func);
+XML_DEPRECATED
XMLPUBFUN xmlOutputBufferCreateFilenameFunc
xmlThrDefOutputBufferCreateFilenameDefault(
xmlOutputBufferCreateFilenameFunc func);
+XML_DEPRECATED
XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
xmlThrDefParserInputBufferCreateFilenameDefault(
xmlParserInputBufferCreateFilenameFunc func);
diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
index 1f0ab4a..36381be 100644
--- a/include/libxml/xmlerror.h
+++ b/include/libxml/xmlerror.h
@@ -211,6 +211,11 @@ typedef enum {
XML_ERR_USER_STOP, /* 111 */
XML_ERR_COMMENT_ABRUPTLY_ENDED, /* 112 */
XML_WAR_ENCODING_MISMATCH, /* 113 */
+ XML_ERR_RESOURCE_LIMIT, /* 114 */
+ XML_ERR_ARGUMENT, /* 115 */
+ XML_ERR_SYSTEM, /* 116 */
+ XML_ERR_REDECL_PREDEF_ENTITY, /* 117 */
+ XML_ERR_INT_SUBSET_NOT_FINISHED, /* 118 */
XML_NS_ERR_XML_NAMESPACE = 200,
XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */
XML_NS_ERR_QNAME, /* 202 */
@@ -473,6 +478,7 @@ typedef enum {
XML_IO_EADDRINUSE, /* 1554 */
XML_IO_EALREADY, /* 1555 */
XML_IO_EAFNOSUPPORT, /* 1556 */
+ XML_IO_UNSUPPORTED_PROTOCOL, /* 1557 */
XML_XINCLUDE_RECURSION=1600,
XML_XINCLUDE_PARSE_VALUE, /* 1601 */
XML_XINCLUDE_ENTITY_DEF_MISMATCH, /* 1602 */
@@ -886,6 +892,7 @@ XML_GLOBALS_ERROR
XMLPUBFUN void
xmlSetGenericErrorFunc (void *ctx,
xmlGenericErrorFunc handler);
+XML_DEPRECATED
XMLPUBFUN void
xmlThrDefSetGenericErrorFunc(void *ctx,
xmlGenericErrorFunc handler);
@@ -896,6 +903,7 @@ XMLPUBFUN void
XMLPUBFUN void
xmlSetStructuredErrorFunc (void *ctx,
xmlStructuredErrorFunc handler);
+XML_DEPRECATED
XMLPUBFUN void
xmlThrDefSetStructuredErrorFunc(void *ctx,
xmlStructuredErrorFunc handler);
@@ -919,11 +927,17 @@ XMLPUBFUN void
xmlParserValidityWarning (void *ctx,
const char *msg,
...) LIBXML_ATTR_FORMAT(2,3);
+/** DOC_DISABLE */
struct _xmlParserInput;
+/** DOC_ENABLE */
XMLPUBFUN void
xmlParserPrintFileInfo (struct _xmlParserInput *input);
XMLPUBFUN void
xmlParserPrintFileContext (struct _xmlParserInput *input);
+XMLPUBFUN void
+xmlFormatError (const xmlError *err,
+ xmlGenericErrorFunc channel,
+ void *data);
/*
* Extended error information routines
diff --git a/include/libxml/xmlexports.h b/include/libxml/xmlexports.h
index 3b063e7..99f9c37 100644
--- a/include/libxml/xmlexports.h
+++ b/include/libxml/xmlexports.h
@@ -9,6 +9,11 @@
#define __XML_EXPORTS_H__
/** DOC_DISABLE */
+
+/*
+ * Symbol visibility
+ */
+
#if defined(_WIN32) || defined(__CYGWIN__)
#ifdef LIBXML_STATIC
#define XMLPUBLIC
@@ -20,30 +25,119 @@
#else /* not Windows */
#define XMLPUBLIC
#endif /* platform switch */
-/** DOC_ENABLE */
-/*
- * XMLPUBFUN:
- *
- * Macro which declares an exportable function
- */
#define XMLPUBFUN XMLPUBLIC
-/**
- * XMLPUBVAR:
- *
- * Macro which declares an exportable variable
- */
#define XMLPUBVAR XMLPUBLIC extern
-/** DOC_DISABLE */
/* Compatibility */
#define XMLCALL
#define XMLCDECL
-#if !defined(LIBXML_DLL_IMPORT)
-#define LIBXML_DLL_IMPORT XMLPUBVAR
+#ifndef LIBXML_DLL_IMPORT
+ #define LIBXML_DLL_IMPORT XMLPUBVAR
+#endif
+
+/*
+ * Attributes
+ */
+
+#if __GNUC__ * 100 + __GNUC_MINOR__ >= 207
+ #define ATTRIBUTE_UNUSED __attribute__((unused))
+#else
+ #define ATTRIBUTE_UNUSED
+#endif
+
+#if !defined(__clang__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
+ #define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+#else
+ #define LIBXML_ATTR_ALLOC_SIZE(x)
+#endif
+
+#if __GNUC__ * 100 + __GNUC_MINOR__ >= 303
+ #define LIBXML_ATTR_FORMAT(fmt,args) \
+ __attribute__((__format__(__printf__,fmt,args)))
+#else
+ #define LIBXML_ATTR_FORMAT(fmt,args)
+#endif
+
+#ifndef XML_DEPRECATED
+ #if defined(IN_LIBXML)
+ #define XML_DEPRECATED
+ #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 301
+ #define XML_DEPRECATED __attribute__((deprecated))
+ #elif _MSC_VER >= 1400
+ /* Available since Visual Studio 2005 */
+ #define XML_DEPRECATED __declspec(deprecated)
+ #else
+ #define XML_DEPRECATED
+ #endif
+#endif
+
+/*
+ * Warnings pragmas, should be moved from public headers
+ */
+
+#if defined(__LCC__)
+
+ #define XML_IGNORE_FPTR_CAST_WARNINGS
+ #define XML_POP_WARNINGS \
+ _Pragma("diag_default 1215")
+
+#elif defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
+
+ #if defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 800)
+ #define XML_IGNORE_FPTR_CAST_WARNINGS \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
+ _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"")
+ #else
+ #define XML_IGNORE_FPTR_CAST_WARNINGS \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
+ #endif
+ #define XML_POP_WARNINGS \
+ _Pragma("GCC diagnostic pop")
+
+#elif _MSC_VER >= 1400
+
+ #define XML_IGNORE_FPTR_CAST_WARNINGS __pragma(warning(push))
+ #define XML_POP_WARNINGS __pragma(warning(pop))
+
+#else
+
+ #define XML_IGNORE_FPTR_CAST_WARNINGS
+ #define XML_POP_WARNINGS
+
+#endif
+
+/*
+ * Accessors for globals
+ */
+
+#define XML_NO_ATTR
+
+#ifdef LIBXML_THREAD_ENABLED
+ #define XML_DECLARE_GLOBAL(name, type, attrs) \
+ attrs XMLPUBFUN type *__##name(void);
+ #define XML_GLOBAL_MACRO(name) (*__##name())
+#else
+ #define XML_DECLARE_GLOBAL(name, type, attrs) \
+ attrs XMLPUBVAR type name;
+#endif
+
+/*
+ * Originally declared in xmlversion.h which is generated
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+XMLPUBFUN void xmlCheckVersion(int version);
+
+#ifdef __cplusplus
+}
#endif
-/** DOC_ENABLE */
#endif /* __XML_EXPORTS_H__ */
diff --git a/include/libxml/xmlmemory.h b/include/libxml/xmlmemory.h
index 097e3c8..1de3e9f 100644
--- a/include/libxml/xmlmemory.h
+++ b/include/libxml/xmlmemory.h
@@ -147,12 +147,16 @@ XMLPUBFUN int
xmlMemUsed (void);
XMLPUBFUN int
xmlMemBlocks (void);
+XML_DEPRECATED
XMLPUBFUN void
xmlMemDisplay (FILE *fp);
+XML_DEPRECATED
XMLPUBFUN void
xmlMemDisplayLast(FILE *fp, long nbBytes);
+XML_DEPRECATED
XMLPUBFUN void
xmlMemShow (FILE *fp, int nr);
+XML_DEPRECATED
XMLPUBFUN void
xmlMemoryDump (void);
XMLPUBFUN void *
@@ -163,60 +167,19 @@ XMLPUBFUN void
xmlMemFree (void *ptr);
XMLPUBFUN char *
xmlMemoryStrdup (const char *str);
+XML_DEPRECATED
XMLPUBFUN void *
xmlMallocLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
+XML_DEPRECATED
XMLPUBFUN void *
xmlReallocLoc (void *ptr, size_t size, const char *file, int line);
+XML_DEPRECATED
XMLPUBFUN void *
xmlMallocAtomicLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
+XML_DEPRECATED
XMLPUBFUN char *
xmlMemStrdupLoc (const char *str, const char *file, int line);
-
-/** DOC_DISABLE */
-#ifdef DEBUG_MEMORY_LOCATION
-/**
- * xmlMalloc:
- * @size: number of bytes to allocate
- *
- * Wrapper for the malloc() function used in the XML library.
- *
- * Returns the pointer to the allocated area or NULL in case of error.
- */
-#define xmlMalloc(size) xmlMallocLoc((size), __FILE__, __LINE__)
-/**
- * xmlMallocAtomic:
- * @size: number of bytes to allocate
- *
- * Wrapper for the malloc() function used in the XML library for allocation
- * of block not containing pointers to other areas.
- *
- * Returns the pointer to the allocated area or NULL in case of error.
- */
-#define xmlMallocAtomic(size) xmlMallocAtomicLoc((size), __FILE__, __LINE__)
-/**
- * xmlRealloc:
- * @ptr: pointer to the existing allocated area
- * @size: number of bytes to allocate
- *
- * Wrapper for the realloc() function used in the XML library.
- *
- * Returns the pointer to the allocated area or NULL in case of error.
- */
-#define xmlRealloc(ptr, size) xmlReallocLoc((ptr), (size), __FILE__, __LINE__)
-/**
- * xmlMemStrdup:
- * @str: pointer to the existing string
- *
- * Wrapper for the strdup() function, xmlStrdup() is usually preferred.
- *
- * Returns the pointer to the allocated area or NULL in case of error.
- */
-#define xmlMemStrdup(str) xmlMemStrdupLoc((str), __FILE__, __LINE__)
-
-#endif /* DEBUG_MEMORY_LOCATION */
-/** DOC_ENABLE */
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/libxml/xmlreader.h b/include/libxml/xmlreader.h
index b9f6989..5d4fc5d 100644
--- a/include/libxml/xmlreader.h
+++ b/include/libxml/xmlreader.h
@@ -127,6 +127,8 @@ XMLPUBFUN int
XMLPUBFUN void
xmlTextReaderSetMaxAmplification(xmlTextReaderPtr reader,
unsigned maxAmpl);
+XMLPUBFUN const xmlError *
+ xmlTextReaderGetLastError(xmlTextReaderPtr reader);
/*
* Iterators
diff --git a/include/libxml/xmlsave.h b/include/libxml/xmlsave.h
index fbf293a..e266e46 100644
--- a/include/libxml/xmlsave.h
+++ b/include/libxml/xmlsave.h
@@ -73,6 +73,8 @@ XMLPUBFUN int
xmlSaveFlush (xmlSaveCtxtPtr ctxt);
XMLPUBFUN int
xmlSaveClose (xmlSaveCtxtPtr ctxt);
+XMLPUBFUN int
+ xmlSaveFinish (xmlSaveCtxtPtr ctxt);
XMLPUBFUN int
xmlSaveSetEscape (xmlSaveCtxtPtr ctxt,
xmlCharEncodingOutputFunc escape);
@@ -80,10 +82,13 @@ XMLPUBFUN int
xmlSaveSetAttrEscape (xmlSaveCtxtPtr ctxt,
xmlCharEncodingOutputFunc escape);
+XML_DEPRECATED
XMLPUBFUN int
xmlThrDefIndentTreeOutput(int v);
+XML_DEPRECATED
XMLPUBFUN const char *
xmlThrDefTreeIndentString(const char * v);
+XML_DEPRECATED
XMLPUBFUN int
xmlThrDefSaveNoEmptyTags(int v);
diff --git a/include/libxml/xmlunicode.h b/include/libxml/xmlunicode.h
index 2e50a49..b6d795b 100644
--- a/include/libxml/xmlunicode.h
+++ b/include/libxml/xmlunicode.h
@@ -7,7 +7,7 @@
* http://www.unicode.org/Public/4.0-Update1/UCD-4.0.1.html
* using the genUnicode.py Python script.
*
- * Generation date: Mon Mar 27 11:09:52 2006
+ * Generation date: Tue Apr 30 17:30:38 2024
* Sources: Blocks-4.0.1.txt UnicodeData-4.0.1.txt
* Author: Daniel Veillard
*/
@@ -23,172 +23,336 @@
extern "C" {
#endif
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsAegeanNumbers (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsAlphabeticPresentationForms (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsArabic (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsArabicPresentationFormsA (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsArabicPresentationFormsB (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsArmenian (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsArrows (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsBasicLatin (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsBengali (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsBlockElements (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsBopomofo (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsBopomofoExtended (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsBoxDrawing (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsBraillePatterns (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsBuhid (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsByzantineMusicalSymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCJKCompatibility (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCJKCompatibilityForms (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCJKCompatibilityIdeographs (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCJKCompatibilityIdeographsSupplement (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCJKRadicalsSupplement (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCJKSymbolsandPunctuation (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCJKUnifiedIdeographs (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCJKUnifiedIdeographsExtensionA (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCJKUnifiedIdeographsExtensionB (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCherokee (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCombiningDiacriticalMarks (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCombiningDiacriticalMarksforSymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCombiningHalfMarks (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCombiningMarksforSymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsControlPictures (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCurrencySymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCypriotSyllabary (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCyrillic (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCyrillicSupplement (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsDeseret (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsDevanagari (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsDingbats (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsEnclosedAlphanumerics (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsEnclosedCJKLettersandMonths (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsEthiopic (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsGeneralPunctuation (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsGeometricShapes (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsGeorgian (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsGothic (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsGreek (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsGreekExtended (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsGreekandCoptic (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsGujarati (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsGurmukhi (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsHalfwidthandFullwidthForms (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsHangulCompatibilityJamo (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsHangulJamo (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsHangulSyllables (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsHanunoo (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsHebrew (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsHighPrivateUseSurrogates (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsHighSurrogates (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsHiragana (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsIPAExtensions (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsIdeographicDescriptionCharacters (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsKanbun (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsKangxiRadicals (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsKannada (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsKatakana (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsKatakanaPhoneticExtensions (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsKhmer (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsKhmerSymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLao (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLatin1Supplement (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLatinExtendedA (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLatinExtendedB (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLatinExtendedAdditional (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLetterlikeSymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLimbu (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLinearBIdeograms (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLinearBSyllabary (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsLowSurrogates (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMalayalam (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMathematicalAlphanumericSymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMathematicalOperators (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMiscellaneousMathematicalSymbolsA (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMiscellaneousMathematicalSymbolsB (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMiscellaneousSymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMiscellaneousSymbolsandArrows (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMiscellaneousTechnical (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMongolian (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMusicalSymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsMyanmar (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsNumberForms (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsOgham (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsOldItalic (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsOpticalCharacterRecognition (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsOriya (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsOsmanya (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsPhoneticExtensions (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsPrivateUse (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsPrivateUseArea (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsRunic (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsShavian (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSinhala (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSmallFormVariants (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSpacingModifierLetters (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSpecials (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSuperscriptsandSubscripts (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSupplementalArrowsA (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSupplementalArrowsB (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSupplementalMathematicalOperators (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSupplementaryPrivateUseAreaA (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSupplementaryPrivateUseAreaB (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsSyriac (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsTagalog (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsTagbanwa (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsTags (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsTaiLe (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsTaiXuanJingSymbols (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsTamil (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsTelugu (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsThaana (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsThai (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsTibetan (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsUgaritic (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsUnifiedCanadianAboriginalSyllabics (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsVariationSelectors (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsVariationSelectorsSupplement (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsYiRadicals (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsYiSyllables (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsYijingHexagramSymbols (int code);
XMLPUBFUN int xmlUCSIsBlock (int code, const char *block);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatC (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatCc (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatCf (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatCo (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatCs (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatL (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatLl (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatLm (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatLo (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatLt (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatLu (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatM (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatMc (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatMe (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatMn (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatN (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatNd (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatNl (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatNo (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatP (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatPc (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatPd (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatPe (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatPf (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatPi (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatPo (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatPs (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatS (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatSc (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatSk (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatSm (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatSo (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatZ (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatZl (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatZp (int code);
+XML_DEPRECATED
XMLPUBFUN int xmlUCSIsCatZs (int code);
XMLPUBFUN int xmlUCSIsCat (int code, const char *cat);
diff --git a/include/libxml/xmlversion.h b/include/libxml/xmlversion.h
index 1218a40..0838bce 100644
--- a/include/libxml/xmlversion.h
+++ b/include/libxml/xmlversion.h
@@ -10,40 +10,26 @@
#ifndef __XML_VERSION_H__
#define __XML_VERSION_H__
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * use those to be sure nothing nasty will happen if
- * your library and includes mismatch
- */
-#ifndef LIBXML2_COMPILING_MSCCDEF
-XMLPUBFUN void xmlCheckVersion(int version);
-#endif /* LIBXML2_COMPILING_MSCCDEF */
-
/**
* LIBXML_DOTTED_VERSION:
*
* the version string like "1.2.3"
*/
-#define LIBXML_DOTTED_VERSION "2.12.8"
+#define LIBXML_DOTTED_VERSION "2.13.0"
/**
* LIBXML_VERSION:
*
* the version number: 1.2.3 value is 10203
*/
-#define LIBXML_VERSION 21208
+#define LIBXML_VERSION 21300
/**
* LIBXML_VERSION_STRING:
*
* the version number string, 1.2.3 value is "10203"
*/
-#define LIBXML_VERSION_STRING "21208"
+#define LIBXML_VERSION_STRING "21300"
/**
* LIBXML_VERSION_EXTRA:
@@ -58,32 +44,7 @@ XMLPUBFUN void xmlCheckVersion(int version);
* Macro to check that the libxml version in use is compatible with
* the version the software has been compiled against
*/
-#define LIBXML_TEST_VERSION xmlCheckVersion(21208);
-
-#ifndef VMS
-#if 0
-/**
- * WITH_TRIO:
- *
- * defined if the trio support need to be configured in
- */
-#define WITH_TRIO
-#else
-/**
- * WITHOUT_TRIO:
- *
- * defined if the trio support should not be configured in
- */
-#define WITHOUT_TRIO
-#endif
-#else /* VMS */
-/**
- * WITH_TRIO:
- *
- * defined if the trio support need to be configured in
- */
-#define WITH_TRIO 1
-#endif /* VMS */
+#define LIBXML_TEST_VERSION xmlCheckVersion(21300);
/**
* LIBXML_THREAD_ENABLED:
@@ -301,24 +262,6 @@ XMLPUBFUN void xmlCheckVersion(int version);
#define LIBXML_DEBUG_ENABLED
#endif
-/**
- * DEBUG_MEMORY_LOCATION:
- *
- * Whether the memory debugging is configured in
- */
-#if 0
-#define DEBUG_MEMORY_LOCATION
-#endif
-
-/**
- * LIBXML_DEBUG_RUNTIME:
- *
- * Removed
- */
-#if 0
-#define LIBXML_DEBUG_RUNTIME
-#endif
-
/**
* LIBXML_UNICODE_ENABLED:
*
@@ -346,17 +289,6 @@ XMLPUBFUN void xmlCheckVersion(int version);
#define LIBXML_AUTOMATA_ENABLED
#endif
-/**
- * LIBXML_EXPR_ENABLED:
- *
- * Whether the formal expressions interfaces are compiled in
- *
- * This code is unused and disabled unconditionally for now.
- */
-#if 0
-#define LIBXML_EXPR_ENABLED
-#endif
-
/**
* LIBXML_SCHEMAS_ENABLED:
*
@@ -410,104 +342,8 @@ XMLPUBFUN void xmlCheckVersion(int version);
#endif
#endif
-#ifdef __GNUC__
-/** DOC_DISABLE */
-
-#ifndef ATTRIBUTE_UNUSED
-# if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))
-# define ATTRIBUTE_UNUSED __attribute__((unused))
-# else
-# define ATTRIBUTE_UNUSED
-# endif
-#endif
-
-#ifndef LIBXML_ATTR_ALLOC_SIZE
-# if (!defined(__clang__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))))
-# define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
-# else
-# define LIBXML_ATTR_ALLOC_SIZE(x)
-# endif
-#else
-# define LIBXML_ATTR_ALLOC_SIZE(x)
-#endif
-
-#ifndef LIBXML_ATTR_FORMAT
-# if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
-# define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
-# else
-# define LIBXML_ATTR_FORMAT(fmt,args)
-# endif
-#else
-# define LIBXML_ATTR_FORMAT(fmt,args)
-#endif
-
-#ifndef XML_DEPRECATED
-# if defined (IN_LIBXML) || (__GNUC__ * 100 + __GNUC_MINOR__ < 301)
-# define XML_DEPRECATED
-/* Available since at least GCC 3.1 */
-# else
-# define XML_DEPRECATED __attribute__((deprecated))
-# endif
-#endif
-
-#if defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
- #if defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 800)
- #define XML_IGNORE_FPTR_CAST_WARNINGS \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
- _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"")
- #else
- #define XML_IGNORE_FPTR_CAST_WARNINGS \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
- #endif
- #define XML_POP_WARNINGS \
- _Pragma("GCC diagnostic pop")
-#else
- #define XML_IGNORE_FPTR_CAST_WARNINGS
- #define XML_POP_WARNINGS
-#endif
-
-#else /* ! __GNUC__ */
-#define ATTRIBUTE_UNUSED
-#define LIBXML_ATTR_ALLOC_SIZE(x)
-#define LIBXML_ATTR_FORMAT(fmt,args)
-#ifndef XML_DEPRECATED
-# if defined (IN_LIBXML) || !defined (_MSC_VER)
-# define XML_DEPRECATED
-/* Available since Visual Studio 2005 */
-# elif defined (_MSC_VER) && (_MSC_VER >= 1400)
-# define XML_DEPRECATED __declspec(deprecated)
-# endif
-#endif
-#if defined (_MSC_VER) && (_MSC_VER >= 1400)
-# define XML_IGNORE_FPTR_CAST_WARNINGS __pragma(warning(push))
-#else
-# define XML_IGNORE_FPTR_CAST_WARNINGS
-#endif
-#ifndef XML_POP_WARNINGS
-# if defined (_MSC_VER) && (_MSC_VER >= 1400)
-# define XML_POP_WARNINGS __pragma(warning(pop))
-# else
-# define XML_POP_WARNINGS
-# endif
-#endif
-#endif /* __GNUC__ */
-
-#define XML_NO_ATTR
-
-#ifdef LIBXML_THREAD_ENABLED
- #define XML_DECLARE_GLOBAL(name, type, attrs) \
- attrs XMLPUBFUN type *__##name(void);
- #define XML_GLOBAL_MACRO(name) (*__##name())
-#else
- #define XML_DECLARE_GLOBAL(name, type, attrs) \
- attrs XMLPUBVAR type name;
-#endif
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+#include
+
#endif
diff --git a/include/libxml/xmlwriter.h b/include/libxml/xmlwriter.h
index 339f251..55f88bc 100644
--- a/include/libxml/xmlwriter.h
+++ b/include/libxml/xmlwriter.h
@@ -478,6 +478,7 @@ extern "C" {
* misc
*/
XMLPUBFUN int xmlTextWriterFlush(xmlTextWriterPtr writer);
+ XMLPUBFUN int xmlTextWriterClose(xmlTextWriterPtr writer);
#ifdef __cplusplus
}
diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h
index 6dae078..b89e105 100644
--- a/include/libxml/xpath.h
+++ b/include/libxml/xpath.h
@@ -515,6 +515,10 @@ XMLPUBFUN xmlXPathContextPtr
xmlXPathNewContext (xmlDocPtr doc);
XMLPUBFUN void
xmlXPathFreeContext (xmlXPathContextPtr ctxt);
+XMLPUBFUN void
+ xmlXPathSetErrorHandler(xmlXPathContextPtr ctxt,
+ xmlStructuredErrorFunc handler,
+ void *context);
XMLPUBFUN int
xmlXPathContextSetCache(xmlXPathContextPtr ctxt,
int active,
diff --git a/include/private/buf.h b/include/private/buf.h
index 6fef4ce..982b9ee 100644
--- a/include/private/buf.h
+++ b/include/private/buf.h
@@ -28,10 +28,6 @@ XML_HIDDEN int
xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len);
XML_HIDDEN int
xmlBufCat(xmlBufPtr buf, const xmlChar *str);
-XML_HIDDEN int
-xmlBufCCat(xmlBufPtr buf, const char *str);
-XML_HIDDEN int
-xmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string);
XML_HIDDEN size_t
xmlBufAvail(const xmlBufPtr buf);
@@ -56,8 +52,6 @@ XML_HIDDEN xmlBufPtr
xmlBufFromBuffer(xmlBufferPtr buffer);
XML_HIDDEN xmlBufferPtr
xmlBufBackToBuffer(xmlBufPtr buf);
-XML_HIDDEN int
-xmlBufMergeBuffer(xmlBufPtr buf, xmlBufferPtr buffer);
XML_HIDDEN int
xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input);
diff --git a/include/private/dict.h b/include/private/dict.h
index 9b0be62..826ac54 100644
--- a/include/private/dict.h
+++ b/include/private/dict.h
@@ -67,6 +67,8 @@ xmlInitRandom(void);
XML_HIDDEN void
xmlCleanupRandom(void);
XML_HIDDEN unsigned
+xmlGlobalRandom(void);
+XML_HIDDEN unsigned
xmlRandom(void);
#endif /* XML_DICT_H_PRIVATE__ */
diff --git a/include/private/entities.h b/include/private/entities.h
index c3f15e6..d262ef4 100644
--- a/include/private/entities.h
+++ b/include/private/entities.h
@@ -9,13 +9,17 @@
*
* XML_ENT_PARSED: The entity was parsed and `children` points to the
* content.
- * XML_ENT_CHECKED: The entity was checked for loops.
+ *
+ * XML_ENT_CHECKED: The entity was checked for loops and amplification.
+ * expandedSize was set.
+ *
+ * XML_ENT_VALIDATED: The entity contains a valid attribute value.
+ * Only used when entities aren't substituted.
*/
-#define XML_ENT_PARSED (1<<0)
-#define XML_ENT_CHECKED (1<<1)
-#define XML_ENT_EXPANDING (1<<2)
-#define XML_ENT_CHECKED_LT (1<<3)
-#define XML_ENT_CONTAINS_LT (1<<4)
+#define XML_ENT_PARSED (1u << 0)
+#define XML_ENT_CHECKED (1u << 1)
+#define XML_ENT_VALIDATED (1u << 2)
+#define XML_ENT_EXPANDING (1u << 3)
XML_HIDDEN xmlChar *
xmlEncodeAttributeEntities(xmlDocPtr doc, const xmlChar *input);
diff --git a/include/private/error.h b/include/private/error.h
index 165b782..506405a 100644
--- a/include/private/error.h
+++ b/include/private/error.h
@@ -4,20 +4,31 @@
#include
#include
+#define MAX_ERR_MSG_SIZE 64000
+
struct _xmlNode;
XML_HIDDEN void
-__xmlRaiseError(xmlStructuredErrorFunc schannel,
- xmlGenericErrorFunc channel, void *data, void *ctx,
- void *nod, int domain, int code, xmlErrorLevel level,
+xmlRaiseMemoryError(xmlStructuredErrorFunc schannel, xmlGenericErrorFunc channel,
+ void *data, int domain, xmlError *error);
+XML_HIDDEN int
+xmlVRaiseError(xmlStructuredErrorFunc schannel, xmlGenericErrorFunc channel,
+ void *data, void *ctx, struct _xmlNode *node,
+ int domain, int code, xmlErrorLevel level,
+ const char *file, int line, const char *str1,
+ const char *str2, const char *str3, int int1, int col,
+ const char *msg, va_list ap);
+XML_HIDDEN int
+__xmlRaiseError(xmlStructuredErrorFunc schannel, xmlGenericErrorFunc channel,
+ void *data, void *ctx, struct _xmlNode *node,
+ int domain, int code, xmlErrorLevel level,
const char *file, int line, const char *str1,
const char *str2, const char *str3, int int1, int col,
const char *msg, ...) LIBXML_ATTR_FORMAT(16,17);
XML_HIDDEN void
-__xmlSimpleError(int domain, int code, struct _xmlNode *node,
- const char *msg, const char *extra) LIBXML_ATTR_FORMAT(4,0);
-XML_HIDDEN void
xmlGenericErrorDefaultFunc(void *ctx, const char *msg,
...) LIBXML_ATTR_FORMAT(2,3);
+XML_HIDDEN const char *
+xmlErrString(xmlParserErrors code);
#endif /* XML_ERROR_H_PRIVATE__ */
diff --git a/include/private/globals.h b/include/private/globals.h
index 5f3f112..828b6d5 100644
--- a/include/private/globals.h
+++ b/include/private/globals.h
@@ -6,4 +6,9 @@ xmlInitGlobalsInternal(void);
XML_HIDDEN void
xmlCleanupGlobalsInternal(void);
+#ifdef LIBXML_THREAD_ENABLED
+XML_HIDDEN unsigned *
+xmlGetLocalRngState(void);
+#endif
+
#endif /* XML_GLOBALS_H_PRIVATE__ */
diff --git a/include/private/io.h b/include/private/io.h
index 5f4b210..a2535ae 100644
--- a/include/private/io.h
+++ b/include/private/io.h
@@ -6,17 +6,30 @@
#include
XML_HIDDEN void
+xmlInitIOCallbacks(void);
+
+XML_HIDDEN int
__xmlIOErr(int domain, int code, const char *extra);
-XML_HIDDEN void
-__xmlLoaderErr(void *ctx, const char *msg,
- const char *filename) LIBXML_ATTR_FORMAT(2,0);
-xmlParserInputBufferPtr
-xmlParserInputBufferCreateString(const xmlChar *str);
+XML_HIDDEN int
+xmlNoNetExists(const char *filename);
+
+XML_HIDDEN int
+xmlParserInputBufferCreateFilenameSafe(const char *URI, xmlCharEncoding enc,
+ xmlParserInputBufferPtr *out);
+
+XML_HIDDEN xmlParserInputBufferPtr
+xmlNewInputBufferString(const char *str, int flags);
+XML_HIDDEN xmlParserInputBufferPtr
+xmlNewInputBufferMemory(const void *mem, size_t size, int flags,
+ xmlCharEncoding enc);
#ifdef LIBXML_OUTPUT_ENABLED
XML_HIDDEN xmlOutputBufferPtr
xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
+XML_HIDDEN void
+xmlOutputBufferWriteQuotedString(xmlOutputBufferPtr buf,
+ const xmlChar *string);
#endif
#endif /* XML_IO_H_PRIVATE__ */
diff --git a/include/private/parser.h b/include/private/parser.h
index 7f8f691..b14bebf 100644
--- a/include/private/parser.h
+++ b/include/private/parser.h
@@ -25,18 +25,41 @@
#define XML_INPUT_AUTO_OTHER (4u << 1)
#define XML_INPUT_USES_ENC_DECL (1u << 4)
#define XML_INPUT_ENCODING_ERROR (1u << 5)
+#define XML_INPUT_PROGRESSIVE (1u << 6)
+#define PARSER_STOPPED(ctxt) ((ctxt)->disableSAX > 1)
+
+#define PARSER_PROGRESSIVE(ctxt) \
+ ((ctxt)->input->flags & XML_INPUT_PROGRESSIVE)
+
+#define PARSER_IN_PE(ctxt) \
+ (((ctxt)->input->entity != NULL) && \
+ (((ctxt)->input->entity->etype == XML_INTERNAL_PARAMETER_ENTITY) || \
+ ((ctxt)->input->entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)))
+
+#define PARSER_EXTERNAL(ctxt) \
+ (((ctxt)->inSubset == 2) || \
+ (((ctxt)->input->entity != NULL) && \
+ ((ctxt)->input->entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)))
+
+XML_HIDDEN void
+xmlCtxtVErr(xmlParserCtxtPtr ctxt, xmlNodePtr node, xmlErrorDomain domain,
+ xmlParserErrors code, xmlErrorLevel level,
+ const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
+ int int1, const char *msg, va_list ap);
XML_HIDDEN void
-xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra);
+xmlCtxtErr(xmlParserCtxtPtr ctxt, xmlNodePtr node, xmlErrorDomain domain,
+ xmlParserErrors code, xmlErrorLevel level,
+ const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
+ int int1, const char *msg, ...);
XML_HIDDEN void
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
XML_HIDDEN void LIBXML_ATTR_FORMAT(3,0)
xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar *str1, const xmlChar *str2);
XML_HIDDEN void
-__xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr,
- const char *msg, const xmlChar *str1,
- const xmlChar *str2) LIBXML_ATTR_FORMAT(3,0);
+xmlCtxtErrIO(xmlParserCtxtPtr ctxt, int code, const char *uri);
+
XML_HIDDEN void
xmlHaltParser(xmlParserCtxtPtr ctxt);
XML_HIDDEN int
@@ -65,4 +88,34 @@ xmlParserNsUpdateSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
XML_HIDDEN void *
xmlParserNsLookupSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix);
+#define XML_INPUT_BUF_STATIC (1u << 1)
+#define XML_INPUT_BUF_ZERO_TERMINATED (1u << 2)
+
+XML_HIDDEN xmlParserInputPtr
+xmlNewInputURL(xmlParserCtxtPtr ctxt, const char *url, const char *publicId,
+ const char *encoding, int flags);
+XML_HIDDEN xmlParserInputPtr
+xmlNewInputMemory(xmlParserCtxtPtr ctxt, const char *url,
+ const void *mem, size_t size,
+ const char *encoding, int flags);
+XML_HIDDEN xmlParserInputPtr
+xmlNewInputString(xmlParserCtxtPtr ctxt, const char *url, const char *str,
+ const char *encoding, int flags);
+XML_HIDDEN xmlParserInputPtr
+xmlNewInputFd(xmlParserCtxtPtr ctxt, const char *filename, int fd,
+ const char *encoding, int flags);
+XML_HIDDEN xmlParserInputPtr
+xmlNewInputIO(xmlParserCtxtPtr ctxt, const char *url,
+ xmlInputReadCallback ioRead,
+ xmlInputCloseCallback ioClose,
+ void *ioCtxt,
+ const char *encoding, int flags);
+XML_HIDDEN xmlParserInputPtr
+xmlNewInputPush(xmlParserCtxtPtr ctxt, const char *url,
+ const char *chunk, int size, const char *encoding);
+
+XML_HIDDEN xmlChar *
+xmlExpandEntitiesInAttValue(xmlParserCtxtPtr ctxt, const xmlChar *str,
+ int normalize);
+
#endif /* XML_PARSER_H_PRIVATE__ */
diff --git a/include/private/regexp.h b/include/private/regexp.h
index f202493..b55c932 100644
--- a/include/private/regexp.h
+++ b/include/private/regexp.h
@@ -3,7 +3,21 @@
#include
+#ifdef LIBXML_REGEXP_ENABLED
+
+/*
+ * -2 and -3 are used by xmlValidateElementType for other things.
+ */
+#define XML_REGEXP_OK 0
+#define XML_REGEXP_NOT_FOUND (-1)
+#define XML_REGEXP_INTERNAL_ERROR (-4)
+#define XML_REGEXP_OUT_OF_MEMORY (-5)
+#define XML_REGEXP_INTERNAL_LIMIT (-6)
+#define XML_REGEXP_INVALID_UTF8 (-7)
+
XML_HIDDEN void
xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
+#endif /* LIBXML_REGEXP_ENABLED */
+
#endif /* XML_REGEXP_H_PRIVATE__ */
diff --git a/include/private/save.h b/include/private/save.h
index 873aad7..5d4a753 100644
--- a/include/private/save.h
+++ b/include/private/save.h
@@ -2,13 +2,19 @@
#define XML_SAVE_H_PRIVATE__
#include
+#include
#include
#ifdef LIBXML_OUTPUT_ENABLED
+XML_HIDDEN int
+xmlSaveNotationDecl(xmlSaveCtxtPtr ctxt, xmlNotationPtr cur);
+XML_HIDDEN int
+xmlSaveNotationTable(xmlSaveCtxtPtr ctxt, xmlNotationTablePtr cur);
+
XML_HIDDEN void
-xmlBufAttrSerializeTxtContent(xmlBufPtr buf, xmlDocPtr doc,
- xmlAttrPtr attr, const xmlChar * string);
+xmlBufAttrSerializeTxtContent(xmlOutputBufferPtr buf, xmlDocPtr doc,
+ const xmlChar *string);
XML_HIDDEN void
xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);
diff --git a/include/private/string.h b/include/private/string.h
index 9665fc4..34f4c96 100644
--- a/include/private/string.h
+++ b/include/private/string.h
@@ -3,6 +3,10 @@
#include
+XML_HIDDEN int
+xmlStrVASPrintf(xmlChar **out, int maxSize, const char *msg, va_list ap);
+XML_HIDDEN int
+xmlStrASPrintf(xmlChar **out, int maxSize, const char *msg, ...);
XML_HIDDEN xmlChar *
xmlEscapeFormatString(xmlChar **msg);
diff --git a/include/private/tree.h b/include/private/tree.h
index fb5e162..2d651d5 100644
--- a/include/private/tree.h
+++ b/include/private/tree.h
@@ -9,10 +9,19 @@
XML_HIDDEN extern int
__xmlRegisterCallbacks;
+XML_HIDDEN int
+xmlSearchNsSafe(xmlNodePtr node, const xmlChar *href, xmlNsPtr *out);
+XML_HIDDEN int
+xmlSearchNsByHrefSafe(xmlNodePtr node, const xmlChar *href, xmlNsPtr *out);
+
+XML_HIDDEN int
+xmlNodeParseContent(xmlNodePtr node, const xmlChar *content, int len);
XML_HIDDEN xmlNodePtr
xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
int extended);
XML_HIDDEN xmlNodePtr
xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
+XML_HIDDEN const xmlChar *
+xmlSplitQName4(const xmlChar *name, xmlChar **prefixPtr);
#endif /* XML_TREE_H_PRIVATE__ */
diff --git a/include/private/xpath.h b/include/private/xpath.h
index 0e8d752..72a6972 100644
--- a/include/private/xpath.h
+++ b/include/private/xpath.h
@@ -1,7 +1,16 @@
#ifndef XML_XPATH_H_PRIVATE__
#define XML_XPATH_H_PRIVATE__
+#include
+
XML_HIDDEN void
xmlInitXPathInternal(void);
+#ifdef LIBXML_XPATH_ENABLED
+XML_HIDDEN void
+xmlXPathErrMemory(xmlXPathContextPtr ctxt);
+XML_HIDDEN void
+xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt);
+#endif
+
#endif /* XML_XPATH_H_PRIVATE__ */
diff --git a/include/private/xzlib.h b/include/private/xzlib.h
index b332698..8505ef3 100644
--- a/include/private/xzlib.h
+++ b/include/private/xzlib.h
@@ -19,7 +19,7 @@ typedef void *xzFile; /* opaque lzma file descriptor */
XML_HIDDEN xzFile
__libxml2_xzopen(const char *path, const char *mode);
XML_HIDDEN xzFile
-__libxml2_xzdopen(int fd, const char *mode);
+__libxml2_xzdopen(const char *path, int fd, const char *mode);
XML_HIDDEN int
__libxml2_xzread(xzFile file, void *buf, unsigned len);
XML_HIDDEN int
diff --git a/legacy.c b/legacy.c
index 4bd25fb..ac80c0e 100644
--- a/legacy.c
+++ b/legacy.c
@@ -11,6 +11,7 @@
#include "libxml.h"
#ifdef LIBXML_LEGACY_ENABLED
+#include
#include
#include
@@ -55,7 +56,7 @@ htmlDecodeEntities(htmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"htmlDecodeEntities() deprecated function reached\n");
deprecated = 1;
}
@@ -416,7 +417,7 @@ xmlDecodeEntities(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlDecodeEntities() deprecated function reached\n");
deprecated = 1;
}
@@ -446,7 +447,7 @@ xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlNamespaceParseNCName() deprecated function reached\n");
deprecated = 1;
}
@@ -481,7 +482,7 @@ xmlNamespaceParseQName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlNamespaceParseQName() deprecated function reached\n");
deprecated = 1;
}
@@ -510,7 +511,7 @@ xmlNamespaceParseNSDef(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlNamespaceParseNSDef() deprecated function reached\n");
deprecated = 1;
}
@@ -533,7 +534,7 @@ xmlParseQuotedString(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlParseQuotedString() deprecated function reached\n");
deprecated = 1;
}
@@ -561,7 +562,7 @@ xmlParseNamespace(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlParseNamespace() deprecated function reached\n");
deprecated = 1;
}
@@ -593,7 +594,7 @@ xmlScanName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlScanName() deprecated function reached\n");
deprecated = 1;
}
@@ -633,7 +634,7 @@ xmlParserHandleReference(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlParserHandleReference() deprecated function reached\n");
deprecated = 1;
}
@@ -659,7 +660,7 @@ xmlHandleEntity(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlHandleEntity() deprecated function reached\n");
deprecated = 1;
}
@@ -683,7 +684,7 @@ xmlNewGlobalNs(xmlDocPtr doc ATTRIBUTE_UNUSED,
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlNewGlobalNs() deprecated function reached\n");
deprecated = 1;
}
@@ -703,7 +704,7 @@ xmlUpgradeOldNs(xmlDocPtr doc ATTRIBUTE_UNUSED)
static int deprecated = 0;
if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"xmlUpgradeOldNs() deprecated function reached\n");
deprecated = 1;
}
@@ -729,15 +730,26 @@ xmlEncodeEntities(xmlDocPtr doc ATTRIBUTE_UNUSED,
static int warning = 1;
if (warning) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Deprecated API xmlEncodeEntities() used\n");
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
" change code to use xmlEncodeEntitiesReentrant()\n");
warning = 0;
}
return (NULL);
}
+/**
+ * xmlSetEntityReferenceFunc:
+ * @func: A valid function
+ *
+ * Set the function to call call back when a xml reference has been made
+ */
+void
+xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func ATTRIBUTE_UNUSED)
+{
+}
+
/************************************************************************
* *
* Old set of SAXv1 functions *
@@ -747,7 +759,7 @@ static int deprecated_v1_msg = 0;
#define DEPRECATED(n) \
if (deprecated_v1_msg == 0) \
- xmlGenericError(xmlGenericErrorContext, \
+ fprintf(stderr, \
"Use of deprecated SAXv1 function %s\n", n); \
deprecated_v1_msg++;
diff --git a/libxml.h b/libxml.h
index 2f72e0a..d94677b 100644
--- a/libxml.h
+++ b/libxml.h
@@ -38,11 +38,6 @@
#define SYSCONFDIR "/etc"
#endif
-#ifdef WITH_TRIO
- #define TRIO_REPLACE_STDIO
- #include "trio.h"
-#endif
-
#if !defined(_WIN32) && \
!defined(__CYGWIN__) && \
(defined(__clang__) || \
@@ -53,16 +48,21 @@
#endif
#if defined(__clang__) || \
- (defined(__GNUC__) && (__GNUC__ >= 8))
+ (defined(__GNUC__) && (__GNUC__ >= 8) && !defined(__EDG__))
#define ATTRIBUTE_NO_SANITIZE(arg) __attribute__((no_sanitize(arg)))
#else
#define ATTRIBUTE_NO_SANITIZE(arg)
#endif
#ifdef __clang__
- #define ATTRIBUTE_NO_SANITIZE_INTEGER \
- ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow") \
- ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
+ #if __clang_major__ >= 12
+ #define ATTRIBUTE_NO_SANITIZE_INTEGER \
+ ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow") \
+ ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
+ #else
+ #define ATTRIBUTE_NO_SANITIZE_INTEGER \
+ ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
+ #endif
#else
#define ATTRIBUTE_NO_SANITIZE_INTEGER
#endif
diff --git a/list.c b/list.c
index 4927a26..20df26c 100644
--- a/list.c
+++ b/list.c
@@ -188,18 +188,13 @@ xmlListPtr
xmlListCreate(xmlListDeallocator deallocator, xmlListDataCompare compare)
{
xmlListPtr l;
- if (NULL == (l = (xmlListPtr )xmlMalloc( sizeof(xmlList)))) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for list");
+ if (NULL == (l = (xmlListPtr )xmlMalloc( sizeof(xmlList))))
return (NULL);
- }
/* Initialize the list to NULL */
memset(l, 0, sizeof(xmlList));
/* Add the sentinel */
if (NULL ==(l->sentinel = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink)))) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for sentinel");
xmlFree(l);
return (NULL);
}
@@ -279,11 +274,8 @@ xmlListInsert(xmlListPtr l, void *data)
lkPlace = xmlListLowerSearch(l, data);
/* Add the new link */
lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
- if (lkNew == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for new link");
+ if (lkNew == NULL)
return (1);
- }
lkNew->data = data;
lkPlace = lkPlace->prev;
lkNew->next = lkPlace->next;
@@ -311,11 +303,8 @@ int xmlListAppend(xmlListPtr l, void *data)
lkPlace = xmlListHigherSearch(l, data);
/* Add the new link */
lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
- if (lkNew == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for new link");
+ if (lkNew == NULL)
return (1);
- }
lkNew->data = data;
lkNew->next = lkPlace->next;
(lkPlace->next)->prev = lkNew;
@@ -548,11 +537,8 @@ xmlListPushFront(xmlListPtr l, void *data)
lkPlace = l->sentinel;
/* Add the new link */
lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
- if (lkNew == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for new link");
+ if (lkNew == NULL)
return (0);
- }
lkNew->data = data;
lkNew->next = lkPlace->next;
(lkPlace->next)->prev = lkNew;
@@ -579,11 +565,8 @@ xmlListPushBack(xmlListPtr l, void *data)
return(0);
lkPlace = l->sentinel->prev;
/* Add the new link */
- if (NULL ==(lkNew = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink)))) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for new link");
+ if (NULL ==(lkNew = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink))))
return (0);
- }
lkNew->data = data;
lkNew->next = lkPlace->next;
(lkPlace->next)->prev = lkNew;
@@ -729,7 +712,7 @@ xmlListMerge(xmlListPtr l1, xmlListPtr l2)
* Returns a new copy of the list or NULL in case of error
*/
xmlListPtr
-xmlListDup(const xmlListPtr old)
+xmlListDup(xmlListPtr old)
{
xmlListPtr cur;
@@ -758,7 +741,7 @@ xmlListDup(const xmlListPtr old)
* Returns 0 in case of success 1 in case of error
*/
int
-xmlListCopy(xmlListPtr cur, const xmlListPtr old)
+xmlListCopy(xmlListPtr cur, xmlListPtr old)
{
/* Walk the old tree and insert the data into the new one */
xmlLinkPtr lk;
diff --git a/nanoftp.c b/nanoftp.c
index 8fbe7aa..fc8f8d7 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -137,9 +137,9 @@ int have_ipv6(void) {
* Handle an out of memory condition
*/
static void
-xmlFTPErrMemory(const char *extra)
+xmlFTPErrMemory(const char *extra ATTRIBUTE_UNUSED)
{
- __xmlSimpleError(XML_FROM_FTP, XML_ERR_NO_MEMORY, NULL, NULL, extra);
+ xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_FTP, NULL);
}
/**
@@ -1923,7 +1923,7 @@ static
void ftpList(void *userData, const char *filename, const char* attrib,
const char *owner, const char *group, unsigned long size, int links,
int year, const char *month, int day, int hour, int minute) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s %s %s %ld %s\n", attrib, owner, group, size, filename);
}
static
@@ -1945,7 +1945,7 @@ int main(int argc, char **argv) {
if (argc > 1) {
ctxt = xmlNanoFTPNewCtxt(argv[1]);
if (xmlNanoFTPConnect(ctxt) < 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Couldn't connect to %s\n", argv[1]);
exit(1);
}
@@ -1954,7 +1954,7 @@ int main(int argc, char **argv) {
} else
ctxt = xmlNanoFTPConnectTo("localhost", 0);
if (ctxt == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Couldn't connect to localhost\n");
exit(1);
}
@@ -1962,7 +1962,7 @@ int main(int argc, char **argv) {
output = fopen("/tmp/tstdata", "w");
if (output != NULL) {
if (xmlNanoFTPGet(ctxt, ftpData, (void *) output, tstfile) < 0)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Failed to get file\n");
}
@@ -1974,7 +1974,7 @@ int main(int argc, char **argv) {
#ifdef STANDALONE
#include
int main(int argc, char **argv) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s : FTP support not compiled in\n", argv[0]);
return(0);
}
diff --git a/nanohttp.c b/nanohttp.c
index ec6b50a..ca68d66 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -150,9 +150,9 @@ static int xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len );
* Handle an out of memory condition
*/
static void
-xmlHTTPErrMemory(const char *extra)
+xmlHTTPErrMemory(void)
{
- __xmlSimpleError(XML_FROM_HTTP, XML_ERR_NO_MEMORY, NULL, NULL, extra);
+ xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_HTTP, NULL);
}
/**
@@ -361,7 +361,7 @@ xmlNanoHTTPNewCtxt(const char *URL) {
ret = (xmlNanoHTTPCtxtPtr) xmlMalloc(sizeof(xmlNanoHTTPCtxt));
if (ret == NULL) {
- xmlHTTPErrMemory("allocating context");
+ xmlHTTPErrMemory();
return(NULL);
}
@@ -507,7 +507,7 @@ xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt)
if (ctxt->in == NULL) {
ctxt->in = (char *) xmlMallocAtomic(65000);
if (ctxt->in == NULL) {
- xmlHTTPErrMemory("allocating input");
+ xmlHTTPErrMemory();
ctxt->last = -1;
return (-1);
}
@@ -532,7 +532,7 @@ xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt)
ctxt->inlen *= 2;
ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen);
if (ctxt->in == NULL) {
- xmlHTTPErrMemory("allocating input buffer");
+ xmlHTTPErrMemory();
xmlFree(tmp_ptr);
ctxt->last = -1;
return (-1);
@@ -1222,8 +1222,10 @@ xmlNanoHTTPRead(void *ctx, void *dest, int len) {
}
if (ctxt->inptr - ctxt->inrptr < len)
len = ctxt->inptr - ctxt->inrptr;
- memcpy(dest, ctxt->inrptr, len);
- ctxt->inrptr += len;
+ if (len > 0) {
+ memcpy(dest, ctxt->inrptr, len);
+ ctxt->inrptr += len;
+ }
return(len);
}
@@ -1391,7 +1393,7 @@ xmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input,
}
if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) {
- __xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Not a valid HTTP URI");
+ __xmlIOErr(XML_FROM_IO, XML_IO_UNSUPPORTED_PROTOCOL, ctxt->protocol);
xmlNanoHTTPFreeCtxt(ctxt);
if (redirURL != NULL) xmlFree(redirURL);
return(NULL);
@@ -1447,7 +1449,7 @@ xmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input,
bp = (char*)xmlMallocAtomic(blen);
if ( bp == NULL ) {
xmlNanoHTTPFreeCtxt( ctxt );
- xmlHTTPErrMemory("allocating header buffer");
+ xmlHTTPErrMemory();
return ( NULL );
}
@@ -1834,9 +1836,9 @@ int main(int argc, char **argv) {
xmlNanoHTTPFetch(argv[1], "-", &contentType);
if (contentType != NULL) xmlFree(contentType);
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s: minimal HTTP GET implementation\n", argv[0]);
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"\tusage %s [ URL [ filename ] ]\n", argv[0]);
}
xmlNanoHTTPCleanup();
@@ -1847,7 +1849,7 @@ int main(int argc, char **argv) {
#ifdef STANDALONE
#include
int main(int argc, char **argv) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"%s : HTTP support not compiled in\n", argv[0]);
return(0);
}
diff --git a/parser.c b/parser.c
index ac621a6..0001ef9 100644
--- a/parser.c
+++ b/parser.c
@@ -108,23 +108,25 @@ struct _xmlParserNsData {
unsigned elementId;
int defaultNsIndex;
+ int minNsIndex;
};
struct _xmlAttrHashBucket {
int index;
};
-static xmlParserCtxtPtr
-xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
- const xmlChar *URL, const xmlChar *ID, const xmlChar *base,
- xmlParserCtxtPtr pctx);
-
static int
xmlParseElementStart(xmlParserCtxtPtr ctxt);
static void
xmlParseElementEnd(xmlParserCtxtPtr ctxt);
+static xmlEntityPtr
+xmlLookupGeneralEntity(xmlParserCtxtPtr ctxt, const xmlChar *name, int inAttr);
+
+static const xmlChar *
+xmlParseEntityRefInternal(xmlParserCtxtPtr ctxt);
+
/************************************************************************
* *
* Arbitrary limits set in the parser. See XML_PARSE_HUGE *
@@ -159,7 +161,7 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt);
* boundary feature. It can be disabled with the XML_PARSE_HUGE
* parser option.
*/
-unsigned int xmlParserMaxDepth = 256;
+const unsigned int xmlParserMaxDepth = 256;
@@ -201,23 +203,8 @@ static const char* const xmlW3CPIs[] = {
static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
const xmlChar **str);
-static xmlParserErrors
-xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
- xmlSAXHandlerPtr sax,
- void *user_data, int depth, const xmlChar *URL,
- const xmlChar *ID, xmlNodePtr *list);
-
-static int
-xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options);
-#ifdef LIBXML_LEGACY_ENABLED
static void
-xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
- xmlNodePtr lastNode);
-#endif /* LIBXML_LEGACY_ENABLED */
-
-static xmlParserErrors
-xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
- const xmlChar *string, void *user_data, xmlNodePtr *lst);
+xmlCtxtParseEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr ent);
static int
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
@@ -228,6 +215,11 @@ xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
* *
************************************************************************/
+static void
+xmlErrMemory(xmlParserCtxtPtr ctxt) {
+ xmlCtxtErrMemory(ctxt);
+}
+
/**
* xmlErrAttributeDup:
* @ctxt: an XML parser context
@@ -240,28 +232,14 @@ static void
xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
const xmlChar * localname)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
-
if (prefix == NULL)
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
- XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
- (const char *) localname, NULL, NULL, 0, 0,
- "Attribute %s redefined\n", localname);
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, XML_ERR_ATTRIBUTE_REDEFINED,
+ XML_ERR_FATAL, localname, NULL, NULL, 0,
+ "Attribute %s redefined\n", localname);
else
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
- XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
- (const char *) prefix, (const char *) localname,
- NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
- localname);
- if (ctxt != NULL) {
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0)
- ctxt->disableSAX = 1;
- }
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, XML_ERR_ATTRIBUTE_REDEFINED,
+ XML_ERR_FATAL, prefix, localname, NULL, 0,
+ "Attribute %s:%s redefined\n", prefix, localname);
}
/**
@@ -276,18 +254,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
- XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
- if (ctxt != NULL) {
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0)
- ctxt->disableSAX = 1;
- }
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
+ NULL, NULL, NULL, 0, "%s", msg);
}
/**
@@ -304,29 +272,8 @@ void LIBXML_ATTR_FORMAT(3,0)
xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar *str1, const xmlChar *str2)
{
- xmlStructuredErrorFunc schannel = NULL;
-
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if ((ctxt != NULL) && (ctxt->sax != NULL) &&
- (ctxt->sax->initialized == XML_SAX2_MAGIC))
- schannel = ctxt->sax->serror;
- if (ctxt != NULL) {
- __xmlRaiseError(schannel,
- (ctxt->sax) ? ctxt->sax->warning : NULL,
- ctxt->userData,
- ctxt, NULL, XML_FROM_PARSER, error,
- XML_ERR_WARNING, NULL, 0,
- (const char *) str1, (const char *) str2, NULL, 0, 0,
- msg, (const char *) str1, (const char *) str2);
- } else {
- __xmlRaiseError(schannel, NULL, NULL,
- ctxt, NULL, XML_FROM_PARSER, error,
- XML_ERR_WARNING, NULL, 0,
- (const char *) str1, (const char *) str2, NULL, 0, 0,
- msg, (const char *) str1, (const char *) str2);
- }
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_WARNING,
+ str1, str2, NULL, 0, msg, str1, str2);
}
/**
@@ -342,31 +289,10 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar *str1, const xmlChar *str2)
{
- xmlStructuredErrorFunc schannel = NULL;
+ ctxt->valid = 0;
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL) {
- ctxt->errNo = error;
- if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
- schannel = ctxt->sax->serror;
- }
- if (ctxt != NULL) {
- __xmlRaiseError(schannel,
- ctxt->vctxt.error, ctxt->vctxt.userData,
- ctxt, NULL, XML_FROM_DTD, error,
- XML_ERR_ERROR, NULL, 0, (const char *) str1,
- (const char *) str2, NULL, 0, 0,
- msg, (const char *) str1, (const char *) str2);
- ctxt->valid = 0;
- } else {
- __xmlRaiseError(schannel, NULL, NULL,
- ctxt, NULL, XML_FROM_DTD, error,
- XML_ERR_ERROR, NULL, 0, (const char *) str1,
- (const char *) str2, NULL, 0, 0,
- msg, (const char *) str1, (const char *) str2);
- }
+ xmlCtxtErr(ctxt, NULL, XML_FROM_DTD, error, XML_ERR_ERROR,
+ str1, str2, NULL, 0, msg, str1, str2);
}
/**
@@ -382,19 +308,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, int val)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL,
- ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
- NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
- if (ctxt != NULL) {
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0)
- ctxt->disableSAX = 1;
- }
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
+ NULL, NULL, NULL, val, msg, val);
}
/**
@@ -413,20 +328,8 @@ xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar *str1, int val,
const xmlChar *str2)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL,
- ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
- NULL, 0, (const char *) str1, (const char *) str2,
- NULL, val, 0, msg, str1, val, str2);
- if (ctxt != NULL) {
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0)
- ctxt->disableSAX = 1;
- }
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
+ str1, str2, NULL, val, msg, str1, val, str2);
}
/**
@@ -442,20 +345,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar * val)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
- XML_FROM_PARSER, error, XML_ERR_FATAL,
- NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
- val);
- if (ctxt != NULL) {
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0)
- ctxt->disableSAX = 1;
- }
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
+ val, NULL, NULL, 0, msg, val);
}
/**
@@ -471,15 +362,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const xmlChar * val)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
- XML_FROM_PARSER, error, XML_ERR_ERROR,
- NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
- val);
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_ERROR,
+ val, NULL, NULL, 0, msg, val);
}
/**
@@ -498,17 +382,10 @@ xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const xmlChar * info1, const xmlChar * info2,
const xmlChar * info3)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
- XML_ERR_ERROR, NULL, 0, (const char *) info1,
- (const char *) info2, (const char *) info3, 0, 0, msg,
- info1, info2, info3);
- if (ctxt != NULL)
- ctxt->nsWellFormed = 0;
+ ctxt->nsWellFormed = 0;
+
+ xmlCtxtErr(ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_ERROR,
+ info1, info2, info3, 0, msg, info1, info2, info3);
}
/**
@@ -527,13 +404,8 @@ xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
const xmlChar * info1, const xmlChar * info2,
const xmlChar * info3)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
- XML_ERR_WARNING, NULL, 0, (const char *) info1,
- (const char *) info2, (const char *) info3, 0, 0, msg,
- info1, info2, info3);
+ xmlCtxtErr(ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_WARNING,
+ info1, info2, info3, 0, msg, info1, info2, info3);
}
static void
@@ -559,7 +431,7 @@ xmlSaturatedAddSizeT(unsigned long *dst, unsigned long val) {
*
* Check for non-linear entity expansion behaviour.
*
- * In some cases like xmlStringDecodeEntities, this function is called
+ * In some cases like xmlExpandEntityInAttValue, this function is called
* for each, possibly nested entity and its unexpanded content length.
*
* In other cases like xmlParseReference, it's only called for each
@@ -580,37 +452,41 @@ static int
xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long extra)
{
unsigned long consumed;
+ unsigned long *expandedSize;
xmlParserInputPtr input = ctxt->input;
xmlEntityPtr entity = input->entity;
+ if ((entity) && (entity->flags & XML_ENT_CHECKED))
+ return(0);
+
/*
* Compute total consumed bytes so far, including input streams of
* external entities.
*/
- consumed = input->parentConsumed;
- if ((entity == NULL) ||
- ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
- ((entity->flags & XML_ENT_PARSED) == 0))) {
- xmlSaturatedAdd(&consumed, input->consumed);
- xmlSaturatedAddSizeT(&consumed, input->cur - input->base);
- }
+ consumed = input->consumed;
+ xmlSaturatedAddSizeT(&consumed, input->cur - input->base);
xmlSaturatedAdd(&consumed, ctxt->sizeentities);
+ if (entity)
+ expandedSize = &entity->expandedSize;
+ else
+ expandedSize = &ctxt->sizeentcopy;
+
/*
* Add extra cost and some fixed cost.
*/
- xmlSaturatedAdd(&ctxt->sizeentcopy, extra);
- xmlSaturatedAdd(&ctxt->sizeentcopy, XML_ENT_FIXED_COST);
+ xmlSaturatedAdd(expandedSize, extra);
+ xmlSaturatedAdd(expandedSize, XML_ENT_FIXED_COST);
/*
* It's important to always use saturation arithmetic when tracking
* entity sizes to make the size checks reliable. If "sizeentcopy"
* overflows, we have to abort.
*/
- if ((ctxt->sizeentcopy > XML_PARSER_ALLOWED_EXPANSION) &&
- ((ctxt->sizeentcopy >= ULONG_MAX) ||
- (ctxt->sizeentcopy / ctxt->maxAmpl > consumed))) {
- xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_LOOP,
+ if ((*expandedSize > XML_PARSER_ALLOWED_EXPANSION) &&
+ ((*expandedSize >= ULONG_MAX) ||
+ (*expandedSize / ctxt->maxAmpl > consumed))) {
+ xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
"Maximum entity amplification factor exceeded, see "
"xmlCtxtSetMaxAmplification.\n");
xmlHaltParser(ctxt);
@@ -809,12 +685,6 @@ xmlHasFeature(xmlFeature feature)
return(0);
#endif
case XML_WITH_DEBUG_MEM:
-#ifdef DEBUG_MEMORY_LOCATION
- return(1);
-#else
- return(0);
-#endif
- case XML_WITH_DEBUG_RUN:
return(0);
case XML_WITH_ZLIB:
#ifdef LIBXML_ZLIB_ENABLED
@@ -840,6 +710,220 @@ xmlHasFeature(xmlFeature feature)
return(0);
}
+/************************************************************************
+ * *
+ * Simple string buffer *
+ * *
+ ************************************************************************/
+
+typedef struct {
+ xmlChar *mem;
+ unsigned size;
+ unsigned cap; /* size < cap */
+ unsigned max; /* size <= max */
+ xmlParserErrors code;
+} xmlSBuf;
+
+static void
+xmlSBufInit(xmlSBuf *buf, unsigned max) {
+ buf->mem = NULL;
+ buf->size = 0;
+ buf->cap = 0;
+ buf->max = max;
+ buf->code = XML_ERR_OK;
+}
+
+static int
+xmlSBufGrow(xmlSBuf *buf, unsigned len) {
+ xmlChar *mem;
+ unsigned cap;
+
+ if (len >= UINT_MAX / 2 - buf->size) {
+ if (buf->code == XML_ERR_OK)
+ buf->code = XML_ERR_RESOURCE_LIMIT;
+ return(-1);
+ }
+
+ cap = (buf->size + len) * 2;
+ if (cap < 240)
+ cap = 240;
+
+ mem = xmlRealloc(buf->mem, cap);
+ if (mem == NULL) {
+ buf->code = XML_ERR_NO_MEMORY;
+ return(-1);
+ }
+
+ buf->mem = mem;
+ buf->cap = cap;
+
+ return(0);
+}
+
+static void
+xmlSBufAddString(xmlSBuf *buf, const xmlChar *str, unsigned len) {
+ if (buf->max - buf->size < len) {
+ if (buf->code == XML_ERR_OK)
+ buf->code = XML_ERR_RESOURCE_LIMIT;
+ return;
+ }
+
+ if (buf->cap - buf->size <= len) {
+ if (xmlSBufGrow(buf, len) < 0)
+ return;
+ }
+
+ if (len > 0)
+ memcpy(buf->mem + buf->size, str, len);
+ buf->size += len;
+}
+
+static void
+xmlSBufAddCString(xmlSBuf *buf, const char *str, unsigned len) {
+ xmlSBufAddString(buf, (const xmlChar *) str, len);
+}
+
+static void
+xmlSBufAddChar(xmlSBuf *buf, int c) {
+ xmlChar *end;
+
+ if (buf->max - buf->size < 4) {
+ if (buf->code == XML_ERR_OK)
+ buf->code = XML_ERR_RESOURCE_LIMIT;
+ return;
+ }
+
+ if (buf->cap - buf->size <= 4) {
+ if (xmlSBufGrow(buf, 4) < 0)
+ return;
+ }
+
+ end = buf->mem + buf->size;
+
+ if (c < 0x80) {
+ *end = (xmlChar) c;
+ buf->size += 1;
+ } else {
+ buf->size += xmlCopyCharMultiByte(end, c);
+ }
+}
+
+static void
+xmlSBufAddReplChar(xmlSBuf *buf) {
+ xmlSBufAddCString(buf, "\xEF\xBF\xBD", 3);
+}
+
+static void
+xmlSBufReportError(xmlSBuf *buf, xmlParserCtxtPtr ctxt, const char *errMsg) {
+ if (buf->code == XML_ERR_NO_MEMORY)
+ xmlCtxtErrMemory(ctxt);
+ else
+ xmlFatalErr(ctxt, buf->code, errMsg);
+}
+
+static xmlChar *
+xmlSBufFinish(xmlSBuf *buf, int *sizeOut, xmlParserCtxtPtr ctxt,
+ const char *errMsg) {
+ if (buf->mem == NULL) {
+ buf->mem = xmlMalloc(1);
+ if (buf->mem == NULL) {
+ buf->code = XML_ERR_NO_MEMORY;
+ } else {
+ buf->mem[0] = 0;
+ }
+ } else {
+ buf->mem[buf->size] = 0;
+ }
+
+ if (buf->code == XML_ERR_OK) {
+ if (sizeOut != NULL)
+ *sizeOut = buf->size;
+ return(buf->mem);
+ }
+
+ xmlSBufReportError(buf, ctxt, errMsg);
+
+ xmlFree(buf->mem);
+
+ if (sizeOut != NULL)
+ *sizeOut = 0;
+ return(NULL);
+}
+
+static void
+xmlSBufCleanup(xmlSBuf *buf, xmlParserCtxtPtr ctxt, const char *errMsg) {
+ if (buf->code != XML_ERR_OK)
+ xmlSBufReportError(buf, ctxt, errMsg);
+
+ xmlFree(buf->mem);
+}
+
+static int
+xmlUTF8MultibyteLen(xmlParserCtxtPtr ctxt, const xmlChar *str,
+ const char *errMsg) {
+ int c = str[0];
+ int c1 = str[1];
+
+ if ((c1 & 0xC0) != 0x80)
+ goto encoding_error;
+
+ if (c < 0xE0) {
+ /* 2-byte sequence */
+ if (c < 0xC2)
+ goto encoding_error;
+
+ return(2);
+ } else {
+ int c2 = str[2];
+
+ if ((c2 & 0xC0) != 0x80)
+ goto encoding_error;
+
+ if (c < 0xF0) {
+ /* 3-byte sequence */
+ if (c == 0xE0) {
+ /* overlong */
+ if (c1 < 0xA0)
+ goto encoding_error;
+ } else if (c == 0xED) {
+ /* surrogate */
+ if (c1 >= 0xA0)
+ goto encoding_error;
+ } else if (c == 0xEF) {
+ /* U+FFFE and U+FFFF are invalid Chars */
+ if ((c1 == 0xBF) && (c2 >= 0xBE))
+ xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR, errMsg);
+ }
+
+ return(3);
+ } else {
+ /* 4-byte sequence */
+ if ((str[3] & 0xC0) != 0x80)
+ goto encoding_error;
+ if (c == 0xF0) {
+ /* overlong */
+ if (c1 < 0x90)
+ goto encoding_error;
+ } else if (c >= 0xF4) {
+ /* greater than 0x10FFFF */
+ if ((c > 0xF4) || (c1 >= 0x90))
+ goto encoding_error;
+ }
+
+ return(4);
+ }
+ }
+
+encoding_error:
+ /* Only report the first error */
+ if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
+ xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
+ ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
+ }
+
+ return(0);
+}
+
/************************************************************************
* *
* SAX2 defaulted attributes handling *
@@ -847,18 +931,25 @@ xmlHasFeature(xmlFeature feature)
************************************************************************/
/**
- * xmlDetectSAX2:
+ * xmlCtxtInitializeLate:
* @ctxt: an XML parser context
*
- * Do the SAX2 detection and specific initialization
+ * Final initialization of the parser context before starting to parse.
+ *
+ * This accounts for users modifying struct members of parser context
+ * directly.
*/
static void
-xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
+xmlCtxtInitializeLate(xmlParserCtxtPtr ctxt) {
xmlSAXHandlerPtr sax;
/* Avoid unused variable warning if features are disabled. */
(void) sax;
+ /*
+ * Changing the SAX struct directly is still widespread practice
+ * in internal and external code.
+ */
if (ctxt == NULL) return;
sax = ctxt->sax;
#ifdef LIBXML_SAX1_ENABLED
@@ -866,7 +957,9 @@ xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
* Only enable SAX2 if there SAX2 element handlers, except when there
* are no element handlers at all.
*/
- if ((sax) && (sax->initialized == XML_SAX2_MAGIC) &&
+ if (((ctxt->options & XML_PARSE_SAX1) == 0) &&
+ (sax) &&
+ (sax->initialized == XML_SAX2_MAGIC) &&
((sax->startElementNs != NULL) ||
(sax->endElementNs != NULL) ||
((sax->startElement == NULL) && (sax->endElement == NULL))))
@@ -875,12 +968,16 @@ xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
ctxt->sax2 = 1;
#endif /* LIBXML_SAX1_ENABLED */
+ /*
+ * Some users replace the dictionary directly in the context struct.
+ * We really need an API function to do that cleanly.
+ */
ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
(ctxt->str_xml_ns == NULL)) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
}
}
@@ -945,65 +1042,6 @@ xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
return(dst);
}
-/**
- * xmlAttrNormalizeSpace2:
- * @src: the source string
- *
- * Normalize the space in non CDATA attribute values, a slightly more complex
- * front end to avoid allocation problems when running on attribute values
- * coming from the input.
- *
- * Returns a pointer to the normalized value (dst) or NULL if no conversion
- * is needed.
- */
-static const xmlChar *
-xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
-{
- int i;
- int remove_head = 0;
- int need_realloc = 0;
- const xmlChar *cur;
-
- if ((ctxt == NULL) || (src == NULL) || (len == NULL))
- return(NULL);
- i = *len;
- if (i <= 0)
- return(NULL);
-
- cur = src;
- while (*cur == 0x20) {
- cur++;
- remove_head++;
- }
- while (*cur != 0) {
- if (*cur == 0x20) {
- cur++;
- if ((*cur == 0x20) || (*cur == 0)) {
- need_realloc = 1;
- break;
- }
- } else
- cur++;
- }
- if (need_realloc) {
- xmlChar *ret;
-
- ret = xmlStrndup(src + remove_head, i - remove_head + 1);
- if (ret == NULL) {
- xmlErrMemory(ctxt, NULL);
- return(NULL);
- }
- xmlAttrNormalizeSpace(ret, ret);
- *len = strlen((const char *)ret);
- return(ret);
- } else if (remove_head) {
- *len -= remove_head;
- memmove(src, src + remove_head, 1 + *len);
- return(src);
- }
- return(NULL);
-}
-
/**
* xmlAddDefAttrs:
* @ctxt: an XML parser context
@@ -1115,13 +1153,13 @@ xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
attr->prefix = prefix;
attr->value = hvalue;
attr->valueEnd = hvalue.name + len;
- attr->external = ctxt->external;
+ attr->external = PARSER_EXTERNAL(ctxt);
attr->expandedSize = expandedSize;
return;
mem_error:
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return;
}
@@ -1146,15 +1184,13 @@ xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
goto mem_error;
}
- if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
- return;
-
- xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
- (void *) (ptrdiff_t) type);
+ if (xmlHashAdd2(ctxt->attsSpecial, fullname, fullattr,
+ (void *) (ptrdiff_t) type) < 0)
+ goto mem_error;
return;
mem_error:
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return;
}
@@ -1399,8 +1435,8 @@ xmlCheckLanguageID(const xmlChar * lang)
* *
************************************************************************/
-static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
- const xmlChar ** str);
+static xmlChar *
+xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar **str);
/**
* xmlParserNsCreate:
@@ -1545,8 +1581,12 @@ xmlParserNsLookupUri(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix) {
if (prefix->name == ctxt->str_xml)
return(ctxt->str_xml_ns);
+ /*
+ * minNsIndex is used when building an entity tree. We must
+ * ignore namespaces declared outside the entity.
+ */
nsIndex = xmlParserNsLookup(ctxt, prefix, NULL);
- if (nsIndex == INT_MAX)
+ if ((nsIndex == INT_MAX) || (nsIndex < ctxt->nsdb->minNsIndex))
return(NULL);
ret = ctxt->nsTab[nsIndex * 2 + 1];
@@ -1579,7 +1619,7 @@ xmlParserNsLookupSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
else
hprefix.hashValue = 0;
nsIndex = xmlParserNsLookup(ctxt, &hprefix, NULL);
- if (nsIndex == INT_MAX)
+ if ((nsIndex == INT_MAX) || (nsIndex < ctxt->nsdb->minNsIndex))
return(NULL);
return(ctxt->nsdb->extra[nsIndex].saxData);
@@ -1612,7 +1652,7 @@ xmlParserNsUpdateSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
else
hprefix.hashValue = 0;
nsIndex = xmlParserNsLookup(ctxt, &hprefix, NULL);
- if (nsIndex == INT_MAX)
+ if ((nsIndex == INT_MAX) || (nsIndex < ctxt->nsdb->minNsIndex))
return(-1);
ctxt->nsdb->extra[nsIndex].saxData = saxData;
@@ -1651,7 +1691,7 @@ xmlParserNsGrow(xmlParserCtxtPtr ctxt) {
return(0);
error:
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(-1);
}
@@ -1680,7 +1720,7 @@ xmlParserNsPush(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
return(0);
if ((ctxt->nsNr >= ctxt->nsMax) && (xmlParserNsGrow(ctxt) < 0)) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(-1);
}
@@ -1746,13 +1786,13 @@ xmlParserNsPush(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
unsigned newSize, i, index;
if (ctxt->nsdb->hashSize > UINT_MAX / 2) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(-1);
}
newSize = ctxt->nsdb->hashSize ? ctxt->nsdb->hashSize * 2 : 16;
newHash = xmlMalloc(newSize * sizeof(newHash[0]));
if (newHash == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(-1);
}
memset(newHash, 0, newSize * sizeof(newHash[0]));
@@ -1880,7 +1920,7 @@ xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
}
return(ctxt->maxatts);
mem_error:
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(-1);
}
@@ -1905,7 +1945,7 @@ inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
tmp = (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
newSize * sizeof(*tmp));
if (tmp == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return (-1);
}
ctxt->inputTab = tmp;
@@ -1955,7 +1995,19 @@ inputPop(xmlParserCtxtPtr ctxt)
int
nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
{
- if (ctxt == NULL) return(0);
+ int maxDepth;
+
+ if (ctxt == NULL)
+ return(0);
+
+ maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 2048 : 256;
+ if (ctxt->nodeNr > maxDepth) {
+ xmlFatalErrMsgInt(ctxt, XML_ERR_RESOURCE_LIMIT,
+ "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
+ ctxt->nodeNr);
+ xmlHaltParser(ctxt);
+ return(-1);
+ }
if (ctxt->nodeNr >= ctxt->nodeMax) {
xmlNodePtr *tmp;
@@ -1963,20 +2015,12 @@ nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
ctxt->nodeMax * 2 *
sizeof(ctxt->nodeTab[0]));
if (tmp == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return (-1);
}
ctxt->nodeTab = tmp;
ctxt->nodeMax *= 2;
}
- if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
- xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
- "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
- xmlParserMaxDepth);
- xmlHaltParser(ctxt);
- return(-1);
- }
ctxt->nodeTab[ctxt->nodeNr] = value;
ctxt->node = value;
return (ctxt->nodeNr++);
@@ -2064,7 +2108,7 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
tag->nsNr = nsNr;
return (ctxt->nameNr++);
mem_error:
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return (-1);
}
#ifdef LIBXML_PUSH_ENABLED
@@ -2125,7 +2169,7 @@ namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
ctxt->name = value;
return (ctxt->nameNr++);
mem_error:
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return (-1);
}
@@ -2164,7 +2208,7 @@ static int spacePush(xmlParserCtxtPtr ctxt, int val) {
tmp = (int *) xmlRealloc(ctxt->spaceTab,
ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
if (tmp == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
ctxt->spaceMax /=2;
return(-1);
}
@@ -2265,18 +2309,21 @@ static int spacePop(xmlParserCtxtPtr ctxt) {
xmlParserGrow(ctxt); \
} while (0)
-/* Don't shrink push parser buffer. */
#define SHRINK \
- if (((ctxt->progressive == 0) || (ctxt->inputNr > 1)) && \
+ if ((!PARSER_PROGRESSIVE(ctxt)) && \
(ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
(ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
xmlParserShrink(ctxt);
-#define GROW if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) \
+#define GROW \
+ if ((!PARSER_PROGRESSIVE(ctxt)) && \
+ (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
xmlParserGrow(ctxt);
#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
+#define SKIP_BLANKS_PE xmlSkipBlankCharsPE(ctxt)
+
#define NEXT xmlNextChar(ctxt)
#define NEXT1 { \
@@ -2306,97 +2353,146 @@ static int spacePop(xmlParserCtxtPtr ctxt) {
*
* DEPRECATED: Internal function, do not use.
*
- * skip all blanks character found at that point in the input streams.
- * It pops up finished entities in the process if allowable at that point.
+ * Skip whitespace in the input stream.
*
* Returns the number of space chars skipped
*/
-
int
xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
+ const xmlChar *cur;
int res = 0;
/*
* It's Okay to use CUR/NEXT here since all the blanks are on
* the ASCII range.
*/
- if (((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) ||
- (ctxt->instate == XML_PARSER_START)) {
- const xmlChar *cur;
- /*
- * if we are in the document content, go really fast
- */
- cur = ctxt->input->cur;
- while (IS_BLANK_CH(*cur)) {
- if (*cur == '\n') {
- ctxt->input->line++; ctxt->input->col = 1;
- } else {
- ctxt->input->col++;
- }
- cur++;
- if (res < INT_MAX)
- res++;
- if (*cur == 0) {
- ctxt->input->cur = cur;
- xmlParserGrow(ctxt);
- cur = ctxt->input->cur;
- }
- }
- ctxt->input->cur = cur;
- } else {
- int expandPE = ((ctxt->external != 0) || (ctxt->inputNr != 1));
+ cur = ctxt->input->cur;
+ while (IS_BLANK_CH(*cur)) {
+ if (*cur == '\n') {
+ ctxt->input->line++; ctxt->input->col = 1;
+ } else {
+ ctxt->input->col++;
+ }
+ cur++;
+ if (res < INT_MAX)
+ res++;
+ if (*cur == 0) {
+ ctxt->input->cur = cur;
+ xmlParserGrow(ctxt);
+ cur = ctxt->input->cur;
+ }
+ }
+ ctxt->input->cur = cur;
- while (ctxt->instate != XML_PARSER_EOF) {
- if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */
- NEXT;
- } else if (CUR == '%') {
- /*
- * Need to handle support of entities branching here
- */
- if ((expandPE == 0) || (IS_BLANK_CH(NXT(1))) || (NXT(1) == 0))
- break;
- xmlParsePEReference(ctxt);
- } else if (CUR == 0) {
- unsigned long consumed;
- xmlEntityPtr ent;
+ return(res);
+}
- if (ctxt->inputNr <= 1)
- break;
+static void
+xmlPopPE(xmlParserCtxtPtr ctxt) {
+ unsigned long consumed;
+ xmlEntityPtr ent;
- consumed = ctxt->input->consumed;
- xmlSaturatedAddSizeT(&consumed,
- ctxt->input->cur - ctxt->input->base);
+ ent = ctxt->input->entity;
- /*
- * Add to sizeentities when parsing an external entity
- * for the first time.
- */
- ent = ctxt->input->entity;
- if ((ent->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
- ((ent->flags & XML_ENT_PARSED) == 0)) {
- ent->flags |= XML_ENT_PARSED;
+ ent->flags &= ~XML_ENT_EXPANDING;
- xmlSaturatedAdd(&ctxt->sizeentities, consumed);
- }
+ if ((ent->flags & XML_ENT_CHECKED) == 0) {
+ int result;
- xmlParserEntityCheck(ctxt, consumed);
+ /*
+ * Read the rest of the stream in case of errors. We want
+ * to account for the whole entity size.
+ */
+ do {
+ ctxt->input->cur = ctxt->input->end;
+ xmlParserShrink(ctxt);
+ result = xmlParserGrow(ctxt);
+ } while (result > 0);
- xmlPopInput(ctxt);
- } else {
+ consumed = ctxt->input->consumed;
+ xmlSaturatedAddSizeT(&consumed,
+ ctxt->input->end - ctxt->input->base);
+
+ xmlSaturatedAdd(&ent->expandedSize, consumed);
+
+ /*
+ * Add to sizeentities when parsing an external entity
+ * for the first time.
+ */
+ if (ent->etype == XML_EXTERNAL_PARAMETER_ENTITY) {
+ xmlSaturatedAdd(&ctxt->sizeentities, consumed);
+ }
+
+ ent->flags |= XML_ENT_CHECKED;
+ }
+
+ xmlPopInput(ctxt);
+
+ xmlParserEntityCheck(ctxt, ent->expandedSize);
+}
+
+/**
+ * xmlSkipBlankCharsPE:
+ * @ctxt: the XML parser context
+ *
+ * Skip whitespace in the input stream, also handling parameter
+ * entities.
+ *
+ * Returns the number of space chars skipped
+ */
+static int
+xmlSkipBlankCharsPE(xmlParserCtxtPtr ctxt) {
+ int res = 0;
+ int inParam;
+ int expandParam;
+
+ inParam = PARSER_IN_PE(ctxt);
+ expandParam = PARSER_EXTERNAL(ctxt);
+
+ if (!inParam && !expandParam)
+ return(xmlSkipBlankChars(ctxt));
+
+ while (PARSER_STOPPED(ctxt) == 0) {
+ if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */
+ NEXT;
+ } else if (CUR == '%') {
+ if ((expandParam == 0) ||
+ (IS_BLANK_CH(NXT(1))) || (NXT(1) == 0))
break;
- }
/*
- * Also increase the counter when entering or exiting a PERef.
- * The spec says: "When a parameter-entity reference is recognized
- * in the DTD and included, its replacement text MUST be enlarged
- * by the attachment of one leading and one following space (#x20)
- * character."
+ * Expand parameter entity. We continue to consume
+ * whitespace at the start of the entity and possible
+ * even consume the whole entity and pop it. We might
+ * even pop multiple PEs in this loop.
*/
- if (res < INT_MAX)
- res++;
+ xmlParsePEReference(ctxt);
+
+ inParam = PARSER_IN_PE(ctxt);
+ expandParam = PARSER_EXTERNAL(ctxt);
+ } else if (CUR == 0) {
+ if (inParam == 0)
+ break;
+
+ xmlPopPE(ctxt);
+
+ inParam = PARSER_IN_PE(ctxt);
+ expandParam = PARSER_EXTERNAL(ctxt);
+ } else {
+ break;
}
+
+ /*
+ * Also increase the counter when entering or exiting a PERef.
+ * The spec says: "When a parameter-entity reference is recognized
+ * in the DTD and included, its replacement text MUST be enlarged
+ * by the attachment of one leading and one following space (#x20)
+ * character."
+ */
+ if (res < INT_MAX)
+ res++;
}
+
return(res);
}
@@ -2420,16 +2516,7 @@ xmlPopInput(xmlParserCtxtPtr ctxt) {
xmlParserInputPtr input;
if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "Popping input %d\n", ctxt->inputNr);
- if ((ctxt->inputNr > 1) && (ctxt->inSubset == 0) &&
- (ctxt->instate != XML_PARSER_EOF))
- xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
- "Unfinished entity outside the DTD");
input = inputPop(ctxt);
- if (input->entity != NULL)
- input->entity->flags &= ~XML_ENT_EXPANDING;
xmlFreeInputStream(input);
if (*ctxt->input->cur == 0)
xmlParserGrow(ctxt);
@@ -2441,33 +2528,29 @@ xmlPopInput(xmlParserCtxtPtr ctxt) {
* @ctxt: an XML parser context
* @input: an XML parser input fragment (entity, XML fragment ...).
*
- * xmlPushInput: switch to a new input stream which is stacked on top
- * of the previous one(s).
- * Returns -1 in case of error or the index in the input stack
+ * Push an input stream onto the stack.
+ *
+ * This makes the parser use an input returned from advanced functions
+ * like xmlNewInputURL or xmlNewInputMemory.
+ *
+ * Returns -1 in case of error or the index in the input stack
*/
int
xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
+ int maxDepth;
int ret;
- if (input == NULL) return(-1);
-
- if (xmlParserDebugEntities) {
- if ((ctxt->input != NULL) && (ctxt->input->filename))
- xmlGenericError(xmlGenericErrorContext,
- "%s(%d): ", ctxt->input->filename,
- ctxt->input->line);
- xmlGenericError(xmlGenericErrorContext,
- "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
- }
- if (((ctxt->inputNr > 40) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
- (ctxt->inputNr > 100)) {
- xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
- while (ctxt->inputNr > 1)
- xmlFreeInputStream(inputPop(ctxt));
+
+ if ((ctxt == NULL) || (input == NULL))
+ return(-1);
+
+ maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 40 : 20;
+ if (ctxt->inputNr > maxDepth) {
+ xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
+ "Maximum entity nesting depth exceeded");
+ xmlHaltParser(ctxt);
return(-1);
}
ret = inputPush(ctxt, input);
- if (ctxt->instate == XML_PARSER_EOF)
- return(-1);
GROW;
return(ret);
}
@@ -2501,12 +2584,10 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) {
(NXT(2) == 'x')) {
SKIP(3);
GROW;
- while (RAW != ';') { /* loop blocked by count */
+ while ((RAW != ';') && (PARSER_STOPPED(ctxt) == 0)) {
if (count++ > 20) {
count = 0;
GROW;
- if (ctxt->instate == XML_PARSER_EOF)
- return(0);
}
if ((RAW >= '0') && (RAW <= '9'))
val = val * 16 + (CUR - '0');
@@ -2537,8 +2618,6 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) {
if (count++ > 20) {
count = 0;
GROW;
- if (ctxt->instate == XML_PARSER_EOF)
- return(0);
}
if ((RAW >= '0') && (RAW <= '9'))
val = val * 10 + (CUR - '0');
@@ -2713,288 +2792,9 @@ xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
*/
void
xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
- switch(ctxt->instate) {
- case XML_PARSER_CDATA_SECTION:
- return;
- case XML_PARSER_COMMENT:
- return;
- case XML_PARSER_START_TAG:
- return;
- case XML_PARSER_END_TAG:
- return;
- case XML_PARSER_EOF:
- xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
- return;
- case XML_PARSER_PROLOG:
- case XML_PARSER_START:
- case XML_PARSER_XML_DECL:
- case XML_PARSER_MISC:
- xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
- return;
- case XML_PARSER_ENTITY_DECL:
- case XML_PARSER_CONTENT:
- case XML_PARSER_ATTRIBUTE_VALUE:
- case XML_PARSER_PI:
- case XML_PARSER_SYSTEM_LITERAL:
- case XML_PARSER_PUBLIC_LITERAL:
- /* we just ignore it there */
- return;
- case XML_PARSER_EPILOG:
- xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
- return;
- case XML_PARSER_ENTITY_VALUE:
- /*
- * NOTE: in the case of entity values, we don't do the
- * substitution here since we need the literal
- * entity value to be able to save the internal
- * subset of the document.
- * This will be handled by xmlStringDecodeEntities
- */
- return;
- case XML_PARSER_DTD:
- /*
- * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
- * In the internal DTD subset, parameter-entity references
- * can occur only where markup declarations can occur, not
- * within markup declarations.
- * In that case this is handled in xmlParseMarkupDecl
- */
- if ((ctxt->external == 0) && (ctxt->inputNr == 1))
- return;
- if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
- return;
- break;
- case XML_PARSER_IGNORE:
- return;
- }
-
xmlParsePEReference(ctxt);
}
-/*
- * Macro used to grow the current buffer.
- * buffer##_size is expected to be a size_t
- * mem_error: is expected to handle memory allocation failures
- */
-#define growBuffer(buffer, n) { \
- xmlChar *tmp; \
- size_t new_size = buffer##_size * 2 + n; \
- if (new_size < buffer##_size) goto mem_error; \
- tmp = (xmlChar *) xmlRealloc(buffer, new_size); \
- if (tmp == NULL) goto mem_error; \
- buffer = tmp; \
- buffer##_size = new_size; \
-}
-
-/**
- * xmlStringDecodeEntitiesInt:
- * @ctxt: the parser context
- * @str: the input string
- * @len: the string length
- * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
- * @end: an end marker xmlChar, 0 if none
- * @end2: an end marker xmlChar, 0 if none
- * @end3: an end marker xmlChar, 0 if none
- * @check: whether to perform entity checks
- */
-static xmlChar *
-xmlStringDecodeEntitiesInt(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
- int what, xmlChar end, xmlChar end2, xmlChar end3,
- int check) {
- xmlChar *buffer = NULL;
- size_t buffer_size = 0;
- size_t nbchars = 0;
-
- xmlChar *current = NULL;
- xmlChar *rep = NULL;
- const xmlChar *last;
- xmlEntityPtr ent;
- int c,l;
-
- if (str == NULL)
- return(NULL);
- last = str + len;
-
- if (((ctxt->depth > 40) &&
- ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
- (ctxt->depth > 100)) {
- xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_LOOP,
- "Maximum entity nesting depth exceeded");
- return(NULL);
- }
-
- /*
- * allocate a translation buffer.
- */
- buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
- buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
- if (buffer == NULL) goto mem_error;
-
- /*
- * OK loop until we reach one of the ending char or a size limit.
- * we are operating on already parsed values.
- */
- if (str < last)
- c = CUR_SCHAR(str, l);
- else
- c = 0;
- while ((c != 0) && (c != end) && /* non input consuming loop */
- (c != end2) && (c != end3) &&
- (ctxt->instate != XML_PARSER_EOF)) {
-
- if (c == 0) break;
- if ((c == '&') && (str[1] == '#')) {
- int val = xmlParseStringCharRef(ctxt, &str);
- if (val == 0)
- goto int_error;
- COPY_BUF(buffer, nbchars, val);
- if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
- growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
- }
- } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "String decoding Entity Reference: %.30s\n",
- str);
- ent = xmlParseStringEntityRef(ctxt, &str);
- if ((ent != NULL) &&
- (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
- if (ent->content != NULL) {
- COPY_BUF(buffer, nbchars, ent->content[0]);
- if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
- growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
- }
- } else {
- xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
- "predefined entity has no content\n");
- goto int_error;
- }
- } else if ((ent != NULL) && (ent->content != NULL)) {
- if ((check) && (xmlParserEntityCheck(ctxt, ent->length)))
- goto int_error;
-
- if (ent->flags & XML_ENT_EXPANDING) {
- xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
- xmlHaltParser(ctxt);
- ent->content[0] = 0;
- goto int_error;
- }
-
- ent->flags |= XML_ENT_EXPANDING;
- ctxt->depth++;
- rep = xmlStringDecodeEntitiesInt(ctxt, ent->content,
- ent->length, what, 0, 0, 0, check);
- ctxt->depth--;
- ent->flags &= ~XML_ENT_EXPANDING;
-
- if (rep == NULL) {
- ent->content[0] = 0;
- goto int_error;
- }
-
- current = rep;
- while (*current != 0) { /* non input consuming loop */
- buffer[nbchars++] = *current++;
- if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
- growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
- }
- }
- xmlFree(rep);
- rep = NULL;
- } else if (ent != NULL) {
- int i = xmlStrlen(ent->name);
- const xmlChar *cur = ent->name;
-
- buffer[nbchars++] = '&';
- if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
- growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
- }
- for (;i > 0;i--)
- buffer[nbchars++] = *cur++;
- buffer[nbchars++] = ';';
- }
- } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "String decoding PE Reference: %.30s\n", str);
- ent = xmlParseStringPEReference(ctxt, &str);
- if (ent != NULL) {
- if (ent->content == NULL) {
- /*
- * Note: external parsed entities will not be loaded,
- * it is not required for a non-validating parser to
- * complete external PEReferences coming from the
- * internal subset
- */
- if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
- ((ctxt->options & XML_PARSE_DTDVALID) != 0) ||
- (ctxt->validate != 0)) {
- xmlLoadEntityContent(ctxt, ent);
- } else {
- xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
- "not validating will not read content for PE entity %s\n",
- ent->name, NULL);
- }
- }
-
- if ((check) && (xmlParserEntityCheck(ctxt, ent->length)))
- goto int_error;
-
- if (ent->flags & XML_ENT_EXPANDING) {
- xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
- xmlHaltParser(ctxt);
- if (ent->content != NULL)
- ent->content[0] = 0;
- goto int_error;
- }
-
- ent->flags |= XML_ENT_EXPANDING;
- ctxt->depth++;
- rep = xmlStringDecodeEntitiesInt(ctxt, ent->content,
- ent->length, what, 0, 0, 0, check);
- ctxt->depth--;
- ent->flags &= ~XML_ENT_EXPANDING;
-
- if (rep == NULL) {
- if (ent->content != NULL)
- ent->content[0] = 0;
- goto int_error;
- }
- current = rep;
- while (*current != 0) { /* non input consuming loop */
- buffer[nbchars++] = *current++;
- if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
- growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
- }
- }
- xmlFree(rep);
- rep = NULL;
- }
- } else {
- COPY_BUF(buffer, nbchars, c);
- str += l;
- if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
- growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
- }
- }
- if (str < last)
- c = CUR_SCHAR(str, l);
- else
- c = 0;
- }
- buffer[nbchars] = 0;
- return(buffer);
-
-mem_error:
- xmlErrMemory(ctxt, NULL);
-int_error:
- if (rep != NULL)
- xmlFree(rep);
- if (buffer != NULL)
- xmlFree(buffer);
- return(NULL);
-}
-
/**
* xmlStringLenDecodeEntities:
* @ctxt: the parser context
@@ -3007,23 +2807,21 @@ xmlStringDecodeEntitiesInt(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
*
* DEPRECATED: Internal function, don't use.
*
- * Takes a entity string content and process to do the adequate substitutions.
- *
- * [67] Reference ::= EntityRef | CharRef
- *
- * [69] PEReference ::= '%' Name ';'
- *
* Returns A newly allocated string with the substitution done. The caller
* must deallocate it !
*/
xmlChar *
xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
- int what, xmlChar end, xmlChar end2,
- xmlChar end3) {
+ int what ATTRIBUTE_UNUSED,
+ xmlChar end, xmlChar end2, xmlChar end3) {
if ((ctxt == NULL) || (str == NULL) || (len < 0))
return(NULL);
- return(xmlStringDecodeEntitiesInt(ctxt, str, len, what,
- end, end2, end3, 0));
+
+ if ((str[len] != 0) ||
+ (end != 0) || (end2 != 0) || (end3 != 0))
+ return(NULL);
+
+ return(xmlExpandEntitiesInAttValue(ctxt, str, 0));
}
/**
@@ -3037,21 +2835,20 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
*
* DEPRECATED: Internal function, don't use.
*
- * Takes a entity string content and process to do the adequate substitutions.
- *
- * [67] Reference ::= EntityRef | CharRef
- *
- * [69] PEReference ::= '%' Name ';'
- *
* Returns A newly allocated string with the substitution done. The caller
* must deallocate it !
*/
xmlChar *
-xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
+xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
+ int what ATTRIBUTE_UNUSED,
xmlChar end, xmlChar end2, xmlChar end3) {
- if ((ctxt == NULL) || (str == NULL)) return(NULL);
- return(xmlStringDecodeEntitiesInt(ctxt, str, xmlStrlen(str), what,
- end, end2, end3, 0));
+ if ((ctxt == NULL) || (str == NULL))
+ return(NULL);
+
+ if ((end != 0) || (end2 != 0) || (end3 != 0))
+ return(NULL);
+
+ return(xmlExpandEntitiesInAttValue(ctxt, str, 0));
}
/************************************************************************
@@ -3074,7 +2871,7 @@ xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
int blank_chars) {
- int i, ret;
+ int i;
xmlNodePtr lastChild;
/*
@@ -3104,9 +2901,25 @@ static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
*/
if (ctxt->node == NULL) return(0);
if (ctxt->myDoc != NULL) {
- ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
- if (ret == 0) return(1);
- if (ret == 1) return(0);
+ xmlElementPtr elemDecl = NULL;
+ xmlDocPtr doc = ctxt->myDoc;
+ const xmlChar *prefix = NULL;
+
+ if (ctxt->node->ns)
+ prefix = ctxt->node->ns->prefix;
+ if (doc->intSubset != NULL)
+ elemDecl = xmlHashLookup2(doc->intSubset->elements, ctxt->node->name,
+ prefix);
+ if ((elemDecl == NULL) && (doc->extSubset != NULL))
+ elemDecl = xmlHashLookup2(doc->extSubset->elements, ctxt->node->name,
+ prefix);
+ if (elemDecl != NULL) {
+ if (elemDecl->etype == XML_ELEMENT_TYPE_ELEMENT)
+ return(1);
+ if ((elemDecl->etype == XML_ELEMENT_TYPE_ANY) ||
+ (elemDecl->etype == XML_ELEMENT_TYPE_MIXED))
+ return(0);
+ }
}
/*
@@ -3139,7 +2952,7 @@ static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
* xmlSplitQName:
* @ctxt: an XML parser context
* @name: an XML parser context
- * @prefix: a xmlChar **
+ * @prefixOut: a xmlChar **
*
* parse an UTF8 encoded XML qualified name string
*
@@ -3154,27 +2967,21 @@ static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
*/
xmlChar *
-xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
+xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefixOut) {
xmlChar buf[XML_MAX_NAMELEN + 5];
xmlChar *buffer = NULL;
int len = 0;
int max = XML_MAX_NAMELEN;
xmlChar *ret = NULL;
+ xmlChar *prefix;
const xmlChar *cur = name;
int c;
- if (prefix == NULL) return(NULL);
- *prefix = NULL;
+ if (prefixOut == NULL) return(NULL);
+ *prefixOut = NULL;
if (cur == NULL) return(NULL);
-#ifndef XML_XML_NAMESPACE
- /* xml: prefix is not really a namespace */
- if ((cur[0] == 'x') && (cur[1] == 'm') &&
- (cur[2] == 'l') && (cur[3] == ':'))
- return(xmlStrdup(name));
-#endif
-
/* nasty but well=formed */
if (cur[0] == ':')
return(xmlStrdup(name));
@@ -3193,7 +3000,7 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
buffer = (xmlChar *) xmlMallocAtomic(max);
if (buffer == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(NULL);
}
memcpy(buffer, buf, len);
@@ -3205,7 +3012,7 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
tmp = (xmlChar *) xmlRealloc(buffer, max);
if (tmp == NULL) {
xmlFree(buffer);
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(NULL);
}
buffer = tmp;
@@ -3219,13 +3026,16 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
if ((c == ':') && (*cur == 0)) {
if (buffer != NULL)
xmlFree(buffer);
- *prefix = NULL;
return(xmlStrdup(name));
}
- if (buffer == NULL)
+ if (buffer == NULL) {
ret = xmlStrndup(buf, len);
- else {
+ if (ret == NULL) {
+ xmlErrMemory(ctxt);
+ return(NULL);
+ }
+ } else {
ret = buffer;
buffer = NULL;
max = XML_MAX_NAMELEN;
@@ -3234,9 +3044,15 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
if (c == ':') {
c = *cur;
- *prefix = ret;
+ prefix = ret;
if (c == 0) {
- return(xmlStrndup(BAD_CAST "", 0));
+ ret = xmlStrndup(BAD_CAST "", 0);
+ if (ret == NULL) {
+ xmlFree(prefix);
+ return(NULL);
+ }
+ *prefixOut = prefix;
+ return(ret);
}
len = 0;
@@ -3271,7 +3087,8 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
buffer = (xmlChar *) xmlMallocAtomic(max);
if (buffer == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
+ xmlFree(prefix);
return(NULL);
}
memcpy(buffer, buf, len);
@@ -3282,7 +3099,8 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
max *= 2;
tmp = (xmlChar *) xmlRealloc(buffer, max);
if (tmp == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
+ xmlFree(prefix);
xmlFree(buffer);
return(NULL);
}
@@ -3294,11 +3112,17 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
buffer[len] = 0;
}
- if (buffer == NULL)
+ if (buffer == NULL) {
ret = xmlStrndup(buf, len);
- else {
+ if (ret == NULL) {
+ xmlFree(prefix);
+ return(NULL);
+ }
+ } else {
ret = buffer;
}
+
+ *prefixOut = prefix;
}
return(ret);
@@ -3397,11 +3221,9 @@ xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
return(0);
}
-static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
- int *len, int *alloc, int normalize);
-
static const xmlChar *
xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+ const xmlChar *ret;
int len = 0, l;
int c;
int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
@@ -3486,8 +3308,6 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
c = CUR_CHAR(l);
}
}
- if (ctxt->instate == XML_PARSER_EOF)
- return(NULL);
if (len > maxLength) {
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
return(NULL);
@@ -3503,8 +3323,12 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
return (NULL);
}
if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
- return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
- return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+ ret = xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len);
+ else
+ ret = xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len);
+ if (ret == NULL)
+ xmlErrMemory(ctxt);
+ return(ret);
}
/**
@@ -3535,8 +3359,6 @@ xmlParseName(xmlParserCtxtPtr ctxt) {
XML_MAX_NAME_LENGTH;
GROW;
- if (ctxt->instate == XML_PARSER_EOF)
- return(NULL);
/*
* Accelerator for simple ASCII names
@@ -3562,7 +3384,7 @@ xmlParseName(xmlParserCtxtPtr ctxt) {
ctxt->input->cur = in;
ctxt->input->col += count;
if (ret == NULL)
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(ret);
}
}
@@ -3600,13 +3422,13 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
NEXTL(l);
c = CUR_CHAR(l);
}
- if (ctxt->instate == XML_PARSER_EOF)
- return(ret);
if (len > maxLength) {
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
return(ret);
}
ret = xmlDictLookupHashed(ctxt->dict, (BASE_PTR + startPosition), len);
+ if (ret.name == NULL)
+ xmlErrMemory(ctxt);
return(ret);
}
@@ -3663,7 +3485,7 @@ xmlParseNCName(xmlParserCtxtPtr ctxt) {
ctxt->input->cur = in;
ctxt->input->col += count;
if (ret.name == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
}
return(ret);
}
@@ -3690,8 +3512,6 @@ xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
const xmlChar *ret;
GROW;
- if (ctxt->instate == XML_PARSER_EOF)
- return(NULL);
in = ctxt->input->cur;
while (*in != 0 && *in == *cmp) {
@@ -3734,6 +3554,7 @@ xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
static xmlChar *
xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
xmlChar buf[XML_MAX_NAMELEN + 5];
+ xmlChar *ret;
const xmlChar *cur = *str;
int len = 0, l;
int c;
@@ -3763,7 +3584,7 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
buffer = (xmlChar *) xmlMallocAtomic(max);
if (buffer == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(NULL);
}
memcpy(buffer, buf, len);
@@ -3774,7 +3595,7 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
max *= 2;
tmp = (xmlChar *) xmlRealloc(buffer, max);
if (tmp == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
xmlFree(buffer);
return(NULL);
}
@@ -3799,7 +3620,10 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
return(NULL);
}
*str = cur;
- return(xmlStrndup(buf, len));
+ ret = xmlStrndup(buf, len);
+ if (ret == NULL)
+ xmlErrMemory(ctxt);
+ return(ret);
}
/**
@@ -3820,6 +3644,7 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
xmlChar *
xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
xmlChar buf[XML_MAX_NAMELEN + 5];
+ xmlChar *ret;
int len = 0, l;
int c;
int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
@@ -3842,7 +3667,7 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
buffer = (xmlChar *) xmlMallocAtomic(max);
if (buffer == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(NULL);
}
memcpy(buffer, buf, len);
@@ -3853,7 +3678,7 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
max *= 2;
tmp = (xmlChar *) xmlRealloc(buffer, max);
if (tmp == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
xmlFree(buffer);
return(NULL);
}
@@ -3869,22 +3694,170 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
c = CUR_CHAR(l);
}
buffer[len] = 0;
- if (ctxt->instate == XML_PARSER_EOF) {
- xmlFree(buffer);
- return(NULL);
- }
return(buffer);
}
}
- if (ctxt->instate == XML_PARSER_EOF)
- return(NULL);
if (len == 0)
return(NULL);
if (len > maxLength) {
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
return(NULL);
}
- return(xmlStrndup(buf, len));
+ ret = xmlStrndup(buf, len);
+ if (ret == NULL)
+ xmlErrMemory(ctxt);
+ return(ret);
+}
+
+/**
+ * xmlExpandPEsInEntityValue:
+ * @ctxt: parser context
+ * @buf: string buffer
+ * @str: entity value
+ * @length: size of entity value
+ * @depth: nesting depth
+ *
+ * Validate an entity value and expand parameter entities.
+ */
+static void
+xmlExpandPEsInEntityValue(xmlParserCtxtPtr ctxt, xmlSBuf *buf,
+ const xmlChar *str, int length, int depth) {
+ int maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 40 : 20;
+ const xmlChar *end, *chunk;
+ int c, l;
+
+ if (str == NULL)
+ return;
+
+ depth += 1;
+ if (depth > maxDepth) {
+ xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
+ "Maximum entity nesting depth exceeded");
+ return;
+ }
+
+ end = str + length;
+ chunk = str;
+
+ while ((str < end) && (!PARSER_STOPPED(ctxt))) {
+ c = *str;
+
+ if (c >= 0x80) {
+ l = xmlUTF8MultibyteLen(ctxt, str,
+ "invalid character in entity value\n");
+ if (l == 0) {
+ if (chunk < str)
+ xmlSBufAddString(buf, chunk, str - chunk);
+ xmlSBufAddReplChar(buf);
+ str += 1;
+ chunk = str;
+ } else {
+ str += l;
+ }
+ } else if (c == '&') {
+ if (str[1] == '#') {
+ if (chunk < str)
+ xmlSBufAddString(buf, chunk, str - chunk);
+
+ c = xmlParseStringCharRef(ctxt, &str);
+ if (c == 0)
+ return;
+
+ xmlSBufAddChar(buf, c);
+
+ chunk = str;
+ } else {
+ xmlChar *name;
+
+ /*
+ * General entity references are checked for
+ * syntactic validity.
+ */
+ str++;
+ name = xmlParseStringName(ctxt, &str);
+
+ if ((name == NULL) || (*str++ != ';')) {
+ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
+ "EntityValue: '&' forbidden except for entities "
+ "references\n");
+ xmlFree(name);
+ return;
+ }
+
+ xmlFree(name);
+ }
+ } else if (c == '%') {
+ xmlEntityPtr ent;
+
+ if (chunk < str)
+ xmlSBufAddString(buf, chunk, str - chunk);
+
+ ent = xmlParseStringPEReference(ctxt, &str);
+ if (ent == NULL)
+ return;
+
+ if (!PARSER_EXTERNAL(ctxt)) {
+ xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
+ return;
+ }
+
+ if (ent->content == NULL) {
+ /*
+ * Note: external parsed entities will not be loaded,
+ * it is not required for a non-validating parser to
+ * complete external PEReferences coming from the
+ * internal subset
+ */
+ if (((ctxt->options & XML_PARSE_NO_XXE) == 0) &&
+ ((ctxt->replaceEntities) ||
+ (ctxt->validate))) {
+ xmlLoadEntityContent(ctxt, ent);
+ } else {
+ xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
+ "not validating will not read content for "
+ "PE entity %s\n", ent->name, NULL);
+ }
+ }
+
+ /*
+ * TODO: Skip if ent->content is still NULL.
+ */
+
+ if (xmlParserEntityCheck(ctxt, ent->length))
+ return;
+
+ if (ent->flags & XML_ENT_EXPANDING) {
+ xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+ xmlHaltParser(ctxt);
+ return;
+ }
+
+ ent->flags |= XML_ENT_EXPANDING;
+ xmlExpandPEsInEntityValue(ctxt, buf, ent->content, ent->length,
+ depth);
+ ent->flags &= ~XML_ENT_EXPANDING;
+
+ chunk = str;
+ } else {
+ /* Normal ASCII char */
+ if (!IS_BYTE_CHAR(c)) {
+ xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
+ "invalid character in entity value\n");
+ if (chunk < str)
+ xmlSBufAddString(buf, chunk, str - chunk);
+ xmlSBufAddReplChar(buf);
+ str += 1;
+ chunk = str;
+ } else {
+ str += 1;
+ }
+ }
+ }
+
+ if (chunk < str)
+ xmlSBufAddString(buf, chunk, str - chunk);
+
+ return;
}
/**
@@ -3901,404 +3874,640 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
*
* Returns the EntityValue parsed with reference substituted or NULL
*/
-
xmlChar *
xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- int c, l;
- int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
- XML_MAX_HUGE_LENGTH :
- XML_MAX_TEXT_LENGTH;
- xmlChar stop;
- xmlChar *ret = NULL;
- const xmlChar *cur = NULL;
- xmlParserInputPtr input;
+ unsigned maxLength = (ctxt->options & XML_PARSE_HUGE) ?
+ XML_MAX_HUGE_LENGTH :
+ XML_MAX_TEXT_LENGTH;
+ xmlSBuf buf;
+ const xmlChar *start;
+ int quote, length;
- if (RAW == '"') stop = '"';
- else if (RAW == '\'') stop = '\'';
- else {
- xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
- return(NULL);
- }
- buf = (xmlChar *) xmlMallocAtomic(size);
- if (buf == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlSBufInit(&buf, maxLength);
+
+ GROW;
+
+ quote = CUR;
+ if ((quote != '"') && (quote != '\'')) {
+ xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
return(NULL);
}
+ CUR_PTR++;
- /*
- * The content of the entity definition is copied in a buffer.
- */
+ length = 0;
- ctxt->instate = XML_PARSER_ENTITY_VALUE;
- input = ctxt->input;
- GROW;
- if (ctxt->instate == XML_PARSER_EOF)
- goto error;
- 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
+ * Copy raw content of the entity into a buffer
*/
- while (((IS_CHAR(c)) && ((c != stop) || /* checked */
- (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
- if (len + 5 >= size) {
- xmlChar *tmp;
+ while (1) {
+ int c;
- size *= 2;
- tmp = (xmlChar *) xmlRealloc(buf, size);
- if (tmp == NULL) {
- xmlErrMemory(ctxt, NULL);
- goto error;
- }
- buf = tmp;
- }
- COPY_BUF(buf, len, c);
- NEXTL(l);
+ if (PARSER_STOPPED(ctxt))
+ goto error;
- GROW;
- c = CUR_CHAR(l);
- if (c == 0) {
- GROW;
- c = CUR_CHAR(l);
- }
+ if (CUR_PTR >= ctxt->input->end) {
+ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
+ goto error;
+ }
- if (len > maxLength) {
- xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
- "entity value too long\n");
+ c = CUR;
+
+ if (c == 0) {
+ xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
+ "invalid character in entity value\n");
goto error;
}
+ if (c == quote)
+ break;
+ NEXTL(1);
+ length += 1;
+
+ /*
+ * TODO: Check growth threshold
+ */
+ if (ctxt->input->end - CUR_PTR < 10)
+ GROW;
}
- buf[len] = 0;
- if (ctxt->instate == XML_PARSER_EOF)
- goto error;
- if (c != stop) {
- xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
- goto error;
+
+ start = CUR_PTR - length;
+
+ if (orig != NULL) {
+ *orig = xmlStrndup(start, length);
+ if (*orig == NULL)
+ xmlErrMemory(ctxt);
+ }
+
+ xmlExpandPEsInEntityValue(ctxt, &buf, start, length, ctxt->inputNr);
+
+ NEXTL(1);
+
+ return(xmlSBufFinish(&buf, NULL, ctxt, "entity length too long"));
+
+error:
+ xmlSBufCleanup(&buf, ctxt, "entity length too long");
+ return(NULL);
+}
+
+/**
+ * xmlCheckEntityInAttValue:
+ * @ctxt: parser context
+ * @pent: entity
+ * @depth: nesting depth
+ *
+ * Check an entity reference in an attribute value for validity
+ * without expanding it.
+ */
+static void
+xmlCheckEntityInAttValue(xmlParserCtxtPtr ctxt, xmlEntityPtr pent, int depth) {
+ int maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 40 : 20;
+ const xmlChar *str;
+ unsigned long expandedSize = pent->length;
+ int c, flags;
+
+ depth += 1;
+ if (depth > maxDepth) {
+ xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
+ "Maximum entity nesting depth exceeded");
+ return;
+ }
+
+ if (pent->flags & XML_ENT_EXPANDING) {
+ xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+ xmlHaltParser(ctxt);
+ return;
}
- NEXT;
/*
- * Raise problem w.r.t. '&' and '%' being used in non-entities
- * reference constructs. Note Charref will be handled in
- * xmlStringDecodeEntities()
+ * If we're parsing a default attribute value in DTD content,
+ * the entity might reference other entities which weren't
+ * defined yet, so the check isn't reliable.
*/
- cur = buf;
- while (*cur != 0) { /* non input consuming */
- if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
- xmlChar *name;
- xmlChar tmp = *cur;
- int nameOk = 0;
+ if (ctxt->inSubset == 0)
+ flags = XML_ENT_CHECKED | XML_ENT_VALIDATED;
+ else
+ flags = XML_ENT_VALIDATED;
- cur++;
- name = xmlParseStringName(ctxt, &cur);
- if (name != NULL) {
- nameOk = 1;
- xmlFree(name);
+ str = pent->content;
+ if (str == NULL)
+ goto done;
+
+ /*
+ * Note that entity values are already validated. We only check
+ * for illegal less-than signs and compute the expanded size
+ * of the entity. No special handling for multi-byte characters
+ * is needed.
+ */
+ while (!PARSER_STOPPED(ctxt)) {
+ c = *str;
+
+ if (c != '&') {
+ if (c == 0)
+ break;
+
+ if (c == '<')
+ xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
+ "'<' in entity '%s' is not allowed in attributes "
+ "values\n", pent->name);
+
+ str += 1;
+ } else if (str[1] == '#') {
+ int val;
+
+ val = xmlParseStringCharRef(ctxt, &str);
+ if (val == 0) {
+ pent->content[0] = 0;
+ break;
}
- if ((nameOk == 0) || (*cur != ';')) {
- xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
- "EntityValue: '%c' forbidden except for entities references\n",
- tmp);
- goto error;
- }
- if ((tmp == '%') && (ctxt->inSubset == 1) &&
- (ctxt->inputNr == 1)) {
- xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
- goto error;
- }
- if (*cur == 0)
- break;
- }
- cur++;
+ } else {
+ xmlChar *name;
+ xmlEntityPtr ent;
+
+ name = xmlParseStringEntityRef(ctxt, &str);
+ if (name == NULL) {
+ pent->content[0] = 0;
+ break;
+ }
+
+ ent = xmlLookupGeneralEntity(ctxt, name, /* inAttr */ 1);
+ xmlFree(name);
+
+ if ((ent != NULL) &&
+ (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
+ if ((ent->flags & flags) != flags) {
+ pent->flags |= XML_ENT_EXPANDING;
+ xmlCheckEntityInAttValue(ctxt, ent, depth);
+ pent->flags &= ~XML_ENT_EXPANDING;
+ }
+
+ xmlSaturatedAdd(&expandedSize, ent->expandedSize);
+ xmlSaturatedAdd(&expandedSize, XML_ENT_FIXED_COST);
+ }
+ }
+ }
+
+done:
+ if (ctxt->inSubset == 0)
+ pent->expandedSize = expandedSize;
+
+ pent->flags |= flags;
+}
+
+/**
+ * xmlExpandEntityInAttValue:
+ * @ctxt: parser context
+ * @buf: string buffer
+ * @str: entity or attribute value
+ * @pent: entity for entity value, NULL for attribute values
+ * @normalize: whether to collapse whitespace
+ * @inSpace: whitespace state
+ * @depth: nesting depth
+ * @check: whether to check for amplification
+ *
+ * Expand general entity references in an entity or attribute value.
+ * Perform attribute value normalization.
+ */
+static void
+xmlExpandEntityInAttValue(xmlParserCtxtPtr ctxt, xmlSBuf *buf,
+ const xmlChar *str, xmlEntityPtr pent, int normalize,
+ int *inSpace, int depth, int check) {
+ int maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 40 : 20;
+ int c, chunkSize;
+
+ if (str == NULL)
+ return;
+
+ depth += 1;
+ if (depth > maxDepth) {
+ xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
+ "Maximum entity nesting depth exceeded");
+ return;
+ }
+
+ if (pent != NULL) {
+ if (pent->flags & XML_ENT_EXPANDING) {
+ xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+ xmlHaltParser(ctxt);
+ return;
+ }
+
+ if (check) {
+ if (xmlParserEntityCheck(ctxt, pent->length))
+ return;
+ }
}
+ chunkSize = 0;
+
/*
- * Then PEReference entities are substituted.
- *
- * 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.
+ * Note that entity values are already validated. No special
+ * handling for multi-byte characters is needed.
*/
- ++ctxt->depth;
- ret = xmlStringDecodeEntitiesInt(ctxt, buf, len, XML_SUBSTITUTE_PEREF,
- 0, 0, 0, /* check */ 1);
- --ctxt->depth;
+ while (!PARSER_STOPPED(ctxt)) {
+ c = *str;
- if (orig != NULL) {
- *orig = buf;
- buf = NULL;
+ if (c != '&') {
+ if (c == 0)
+ break;
+
+ /*
+ * If this function is called without an entity, it is used to
+ * expand entities in an attribute content where less-than was
+ * already unscaped and is allowed.
+ */
+ if ((pent != NULL) && (c == '<')) {
+ xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
+ "'<' in entity '%s' is not allowed in attributes "
+ "values\n", pent->name);
+ break;
+ }
+
+ if (c <= 0x20) {
+ if ((normalize) && (*inSpace)) {
+ /* Skip char */
+ if (chunkSize > 0) {
+ xmlSBufAddString(buf, str - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+ } else if (c < 0x20) {
+ if (chunkSize > 0) {
+ xmlSBufAddString(buf, str - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+
+ xmlSBufAddCString(buf, " ", 1);
+ } else {
+ chunkSize += 1;
+ }
+
+ *inSpace = 1;
+ } else {
+ chunkSize += 1;
+ *inSpace = 0;
+ }
+
+ str += 1;
+ } else if (str[1] == '#') {
+ int val;
+
+ if (chunkSize > 0) {
+ xmlSBufAddString(buf, str - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+
+ val = xmlParseStringCharRef(ctxt, &str);
+ if (val == 0) {
+ if (pent != NULL)
+ pent->content[0] = 0;
+ break;
+ }
+
+ if (val == ' ') {
+ if ((!normalize) || (!*inSpace))
+ xmlSBufAddCString(buf, " ", 1);
+ *inSpace = 1;
+ } else {
+ xmlSBufAddChar(buf, val);
+ *inSpace = 0;
+ }
+ } else {
+ xmlChar *name;
+ xmlEntityPtr ent;
+
+ if (chunkSize > 0) {
+ xmlSBufAddString(buf, str - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+
+ name = xmlParseStringEntityRef(ctxt, &str);
+ if (name == NULL) {
+ if (pent != NULL)
+ pent->content[0] = 0;
+ break;
+ }
+
+ ent = xmlLookupGeneralEntity(ctxt, name, /* inAttr */ 1);
+ xmlFree(name);
+
+ if ((ent != NULL) &&
+ (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
+ if (ent->content == NULL) {
+ xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
+ "predefined entity has no content\n");
+ break;
+ }
+
+ xmlSBufAddString(buf, ent->content, ent->length);
+
+ *inSpace = 0;
+ } else if ((ent != NULL) && (ent->content != NULL)) {
+ if (pent != NULL)
+ pent->flags |= XML_ENT_EXPANDING;
+ xmlExpandEntityInAttValue(ctxt, buf, ent->content, ent,
+ normalize, inSpace, depth, check);
+ if (pent != NULL)
+ pent->flags &= ~XML_ENT_EXPANDING;
+ }
+ }
}
-error:
- if (buf != NULL)
- xmlFree(buf);
- return(ret);
+ if (chunkSize > 0)
+ xmlSBufAddString(buf, str - chunkSize, chunkSize);
+
+ return;
+}
+
+/**
+ * xmlExpandEntitiesInAttValue:
+ * @ctxt: parser context
+ * @str: entity or attribute value
+ * @normalize: whether to collapse whitespace
+ *
+ * Expand general entity references in an entity or attribute value.
+ * Perform attribute value normalization.
+ *
+ * Returns the expanded attribtue value.
+ */
+xmlChar *
+xmlExpandEntitiesInAttValue(xmlParserCtxtPtr ctxt, const xmlChar *str,
+ int normalize) {
+ unsigned maxLength = (ctxt->options & XML_PARSE_HUGE) ?
+ XML_MAX_HUGE_LENGTH :
+ XML_MAX_TEXT_LENGTH;
+ xmlSBuf buf;
+ int inSpace = 1;
+
+ xmlSBufInit(&buf, maxLength);
+
+ xmlExpandEntityInAttValue(ctxt, &buf, str, NULL, normalize, &inSpace,
+ ctxt->inputNr, /* check */ 0);
+
+ if ((normalize) && (inSpace) && (buf.size > 0))
+ buf.size--;
+
+ return(xmlSBufFinish(&buf, NULL, ctxt, "AttValue length too long"));
}
/**
- * xmlParseAttValueComplex:
+ * xmlParseAttValueInternal:
* @ctxt: an XML parser context
- * @len: the resulting attribute len
- * @normalize: whether to apply the inner normalization
+ * @len: attribute len result
+ * @alloc: whether the attribute was reallocated as a new string
+ * @normalize: if 1 then further non-CDATA normalization must be done
*
- * parse a value for an attribute, this is the fallback function
- * of xmlParseAttValue() when the attribute parsing requires handling
- * of non-ASCII characters, or normalization compaction.
+ * parse a value for an attribute.
+ * NOTE: if no normalization is needed, the routine will return pointers
+ * directly from the data buffer.
*
- * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
+ * 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 if it was copied, this can be detected by val[*len] == 0.
*/
static xmlChar *
-xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
- xmlChar limit = 0;
- xmlChar *buf = NULL;
- xmlChar *rep = NULL;
- size_t len = 0;
- size_t buf_size = 0;
- size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
- XML_MAX_HUGE_LENGTH :
- XML_MAX_TEXT_LENGTH;
- int c, l, in_space = 0;
- xmlChar *current = NULL;
- xmlEntityPtr ent;
+xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *attlen, int *alloc,
+ int normalize, int isNamespace) {
+ unsigned maxLength = (ctxt->options & XML_PARSE_HUGE) ?
+ XML_MAX_HUGE_LENGTH :
+ XML_MAX_TEXT_LENGTH;
+ xmlSBuf buf;
+ xmlChar *ret;
+ int c, l, quote, flags, chunkSize;
+ int inSpace = 1;
+ int replaceEntities;
- if (NXT(0) == '"') {
- ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
- limit = '"';
- NEXT;
- } else if (NXT(0) == '\'') {
- limit = '\'';
- ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
- NEXT;
- } else {
+ /* Always expand namespace URIs */
+ replaceEntities = (ctxt->replaceEntities) || (isNamespace);
+
+ xmlSBufInit(&buf, maxLength);
+
+ GROW;
+
+ quote = CUR;
+ if ((quote != '"') && (quote != '\'')) {
xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
return(NULL);
}
+ NEXTL(1);
- /*
- * allocate a translation buffer.
- */
- buf_size = XML_PARSER_BUFFER_SIZE;
- buf = (xmlChar *) xmlMallocAtomic(buf_size);
- if (buf == NULL) goto mem_error;
+ if (ctxt->inSubset == 0)
+ flags = XML_ENT_CHECKED | XML_ENT_VALIDATED;
+ else
+ flags = XML_ENT_VALIDATED;
- /*
- * OK loop until we reach one of the ending char or a size limit.
- */
- c = CUR_CHAR(l);
- while (((NXT(0) != limit) && /* checked */
- (IS_CHAR(c)) && (c != '<')) &&
- (ctxt->instate != XML_PARSER_EOF)) {
- if (c == '&') {
- in_space = 0;
- if (NXT(1) == '#') {
- int val = xmlParseCharRef(ctxt);
-
- if (val == '&') {
- if (ctxt->replaceEntities) {
- if (len + 10 > buf_size) {
- growBuffer(buf, 10);
- }
- buf[len++] = '&';
- } else {
- /*
- * The reparsing will be done in xmlStringGetNodeList()
- * called by the attribute() function in SAX.c
- */
- if (len + 10 > buf_size) {
- growBuffer(buf, 10);
- }
- buf[len++] = '&';
- buf[len++] = '#';
- buf[len++] = '3';
- buf[len++] = '8';
- buf[len++] = ';';
- }
- } else if (val != 0) {
- if (len + 10 > buf_size) {
- growBuffer(buf, 10);
- }
- len += xmlCopyChar(0, &buf[len], val);
- }
- } else {
- ent = xmlParseEntityRef(ctxt);
- if ((ent != NULL) &&
- (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
- if (len + 10 > buf_size) {
- growBuffer(buf, 10);
- }
- if ((ctxt->replaceEntities == 0) &&
- (ent->content[0] == '&')) {
- buf[len++] = '&';
- buf[len++] = '#';
- buf[len++] = '3';
- buf[len++] = '8';
- buf[len++] = ';';
- } else {
- buf[len++] = ent->content[0];
- }
- } else if ((ent != NULL) &&
- (ctxt->replaceEntities != 0)) {
- if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
- if (xmlParserEntityCheck(ctxt, ent->length))
- goto error;
+ inSpace = 1;
+ chunkSize = 0;
- ++ctxt->depth;
- rep = xmlStringDecodeEntitiesInt(ctxt, ent->content,
- ent->length, XML_SUBSTITUTE_REF, 0, 0, 0,
- /* check */ 1);
- --ctxt->depth;
- if (rep != NULL) {
- current = rep;
- while (*current != 0) { /* non input consuming */
- if ((*current == 0xD) || (*current == 0xA) ||
- (*current == 0x9)) {
- buf[len++] = 0x20;
- current++;
- } else
- buf[len++] = *current++;
- if (len + 10 > buf_size) {
- growBuffer(buf, 10);
- }
- }
- xmlFree(rep);
- rep = NULL;
- }
- } else {
- if (len + 10 > buf_size) {
- growBuffer(buf, 10);
- }
- if (ent->content != NULL)
- buf[len++] = ent->content[0];
- }
- } else if (ent != NULL) {
- int i = xmlStrlen(ent->name);
- const xmlChar *cur = ent->name;
+ while (1) {
+ if (PARSER_STOPPED(ctxt))
+ goto error;
- /*
- * We also check for recursion and amplification
- * when entities are not substituted. They're
- * often expanded later.
- */
- if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
- (ent->content != NULL)) {
- if ((ent->flags & XML_ENT_CHECKED) == 0) {
- unsigned long oldCopy = ctxt->sizeentcopy;
-
- ctxt->sizeentcopy = ent->length;
-
- ++ctxt->depth;
- rep = xmlStringDecodeEntitiesInt(ctxt,
- ent->content, ent->length,
- XML_SUBSTITUTE_REF, 0, 0, 0,
- /* check */ 1);
- --ctxt->depth;
-
- /*
- * If we're parsing DTD content, the entity
- * might reference other entities which
- * weren't defined yet, so the check isn't
- * reliable.
- */
- if (ctxt->inSubset == 0) {
- ent->flags |= XML_ENT_CHECKED;
- ent->expandedSize = ctxt->sizeentcopy;
- }
+ if (CUR_PTR >= ctxt->input->end) {
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+ "AttValue: ' expected\n");
+ goto error;
+ }
- if (rep != NULL) {
- xmlFree(rep);
- rep = NULL;
- } else {
- ent->content[0] = 0;
- }
+ /*
+ * TODO: Check growth threshold
+ */
+ if (ctxt->input->end - CUR_PTR < 10)
+ GROW;
- if (xmlParserEntityCheck(ctxt, oldCopy))
- goto error;
- } else {
- if (xmlParserEntityCheck(ctxt, ent->expandedSize))
- goto error;
- }
- }
+ c = CUR;
- /*
- * Just output the reference
- */
- buf[len++] = '&';
- while (len + i + 10 > buf_size) {
- growBuffer(buf, i + 10);
- }
- for (;i > 0;i--)
- buf[len++] = *cur++;
- buf[len++] = ';';
- }
- }
- } else {
- if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
- if ((len != 0) || (!normalize)) {
- if ((!normalize) || (!in_space)) {
- COPY_BUF(buf, len, 0x20);
- while (len + 10 > buf_size) {
- growBuffer(buf, 10);
- }
- }
- in_space = 1;
- }
- } else {
- in_space = 0;
- COPY_BUF(buf, len, c);
- if (len + 10 > buf_size) {
- growBuffer(buf, 10);
- }
- }
- NEXTL(l);
+ if (c >= 0x80) {
+ l = xmlUTF8MultibyteLen(ctxt, CUR_PTR,
+ "invalid character in attribute value\n");
+ if (l == 0) {
+ if (chunkSize > 0) {
+ xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+ xmlSBufAddReplChar(&buf);
+ NEXTL(1);
+ } else {
+ chunkSize += l;
+ NEXTL(l);
+ }
+
+ inSpace = 0;
+ } else if (c != '&') {
+ if (c > 0x20) {
+ if (c == quote)
+ break;
+
+ if (c == '<')
+ xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
+
+ chunkSize += 1;
+ inSpace = 0;
+ } else if (!IS_BYTE_CHAR(c)) {
+ xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
+ "invalid character in attribute value\n");
+ if (chunkSize > 0) {
+ xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+ xmlSBufAddReplChar(&buf);
+ inSpace = 0;
+ } else {
+ /* Whitespace */
+ if ((normalize) && (inSpace)) {
+ /* Skip char */
+ if (chunkSize > 0) {
+ xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+ } else if (c < 0x20) {
+ /* Convert to space */
+ if (chunkSize > 0) {
+ xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+
+ xmlSBufAddCString(&buf, " ", 1);
+ } else {
+ chunkSize += 1;
+ }
+
+ inSpace = 1;
+
+ if ((c == 0xD) && (NXT(1) == 0xA))
+ CUR_PTR++;
+ }
+
+ NEXTL(1);
+ } else if (NXT(1) == '#') {
+ int val;
+
+ if (chunkSize > 0) {
+ xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+
+ val = xmlParseCharRef(ctxt);
+ if (val == 0)
+ goto error;
+
+ if ((val == '&') && (!replaceEntities)) {
+ /*
+ * The reparsing will be done in xmlStringGetNodeList()
+ * called by the attribute() function in SAX.c
+ */
+ xmlSBufAddCString(&buf, "&", 5);
+ inSpace = 0;
+ } else if (val == ' ') {
+ if ((!normalize) || (!inSpace))
+ xmlSBufAddCString(&buf, " ", 1);
+ inSpace = 1;
+ } else {
+ xmlSBufAddChar(&buf, val);
+ inSpace = 0;
+ }
+ } else {
+ const xmlChar *name;
+ xmlEntityPtr ent;
+
+ if (chunkSize > 0) {
+ xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
+ chunkSize = 0;
+ }
+
+ name = xmlParseEntityRefInternal(ctxt);
+ if (name == NULL) {
+ /*
+ * Probably a literal '&' which wasn't escaped.
+ * TODO: Handle gracefully in recovery mode.
+ */
+ continue;
+ }
+
+ ent = xmlLookupGeneralEntity(ctxt, name, /* isAttr */ 1);
+ if (ent == NULL)
+ continue;
+
+ if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
+ if ((ent->content[0] == '&') && (!replaceEntities))
+ xmlSBufAddCString(&buf, "&", 5);
+ else
+ xmlSBufAddString(&buf, ent->content, ent->length);
+ inSpace = 0;
+ } else if (replaceEntities) {
+ xmlExpandEntityInAttValue(ctxt, &buf, ent->content, ent,
+ normalize, &inSpace, ctxt->inputNr,
+ /* check */ 1);
+ } else {
+ if ((ent->flags & flags) != flags)
+ xmlCheckEntityInAttValue(ctxt, ent, ctxt->inputNr);
+
+ if (xmlParserEntityCheck(ctxt, ent->expandedSize)) {
+ ent->content[0] = 0;
+ goto error;
+ }
+
+ /*
+ * Just output the reference
+ */
+ xmlSBufAddCString(&buf, "&", 1);
+ xmlSBufAddString(&buf, ent->name, xmlStrlen(ent->name));
+ xmlSBufAddCString(&buf, ";", 1);
+
+ inSpace = 0;
+ }
}
- GROW;
- c = CUR_CHAR(l);
- if (len > maxLength) {
- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
- "AttValue length too long\n");
- goto mem_error;
- }
}
- if (ctxt->instate == XML_PARSER_EOF)
- goto error;
- if ((in_space) && (normalize)) {
- while ((len > 0) && (buf[len - 1] == 0x20)) len--;
- }
- buf[len] = 0;
- if (RAW == '<') {
- xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
- } else if (RAW != limit) {
- if ((c != 0) && (!IS_CHAR(c))) {
- xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
- "invalid character in attribute value\n");
- } else {
- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
- "AttValue: ' expected\n");
+ if ((buf.mem == NULL) && (alloc != NULL)) {
+ ret = (xmlChar *) CUR_PTR - chunkSize;
+
+ if (attlen != NULL)
+ *attlen = chunkSize;
+ if ((normalize) && (inSpace) && (chunkSize > 0))
+ *attlen -= 1;
+ *alloc = 0;
+
+ /* Report potential error */
+ xmlSBufCleanup(&buf, ctxt, "AttValue length too long");
+ } else {
+ if (chunkSize > 0)
+ xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
+
+ if ((normalize) && (inSpace) && (buf.size > 0))
+ buf.size--;
+
+ ret = xmlSBufFinish(&buf, attlen, ctxt, "AttValue length too long");
+
+ if (ret != NULL) {
+ if (attlen != NULL)
+ *attlen = buf.size;
+ if (alloc != NULL)
+ *alloc = 1;
}
- } else
- NEXT;
+ }
- if (attlen != NULL) *attlen = len;
- return(buf);
+ NEXTL(1);
+
+ return(ret);
-mem_error:
- xmlErrMemory(ctxt, NULL);
error:
- if (buf != NULL)
- xmlFree(buf);
- if (rep != NULL)
- xmlFree(rep);
+ xmlSBufCleanup(&buf, ctxt, "AttValue length too long");
return(NULL);
}
@@ -4341,7 +4550,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
xmlChar *
xmlParseAttValue(xmlParserCtxtPtr ctxt) {
if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
- return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
+ return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0, 0));
}
/**
@@ -4367,7 +4576,6 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
XML_MAX_TEXT_LENGTH :
XML_MAX_NAME_LENGTH;
xmlChar stop;
- int state = ctxt->instate;
if (RAW == '"') {
NEXT;
@@ -4382,10 +4590,9 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
buf = (xmlChar *) xmlMallocAtomic(size);
if (buf == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(NULL);
}
- ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
cur = CUR_CHAR(l);
while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
if (len + 5 >= size) {
@@ -4395,8 +4602,7 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
tmp = (xmlChar *) xmlRealloc(buf, size);
if (tmp == NULL) {
xmlFree(buf);
- xmlErrMemory(ctxt, NULL);
- ctxt->instate = (xmlParserInputState) state;
+ xmlErrMemory(ctxt);
return(NULL);
}
buf = tmp;
@@ -4405,18 +4611,12 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
if (len > maxLength) {
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
xmlFree(buf);
- ctxt->instate = (xmlParserInputState) state;
return(NULL);
}
NEXTL(l);
cur = CUR_CHAR(l);
}
buf[len] = 0;
- if (ctxt->instate == XML_PARSER_EOF) {
- xmlFree(buf);
- return(NULL);
- }
- ctxt->instate = (xmlParserInputState) state;
if (!IS_CHAR(cur)) {
xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
} else {
@@ -4448,7 +4648,6 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
XML_MAX_NAME_LENGTH;
xmlChar cur;
xmlChar stop;
- xmlParserInputState oldstate = ctxt->instate;
if (RAW == '"') {
NEXT;
@@ -4462,19 +4661,19 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
}
buf = (xmlChar *) xmlMallocAtomic(size);
if (buf == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return(NULL);
}
- ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
cur = CUR;
- while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
+ while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop) &&
+ (PARSER_STOPPED(ctxt) == 0)) { /* checked */
if (len + 1 >= size) {
xmlChar *tmp;
size *= 2;
tmp = (xmlChar *) xmlRealloc(buf, size);
if (tmp == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
xmlFree(buf);
return(NULL);
}
@@ -4490,16 +4689,11 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
cur = CUR;
}
buf[len] = 0;
- if (ctxt->instate == XML_PARSER_EOF) {
- xmlFree(buf);
- return(NULL);
- }
if (cur != stop) {
xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
} else {
NEXTL(1);
}
- ctxt->instate = oldstate;
return(buf);
}
@@ -4630,8 +4824,7 @@ xmlParseCharDataInternal(xmlParserCtxtPtr ctxt, int partial) {
if (*in == ']') {
if ((in[1] == ']') && (in[2] == '>')) {
xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
- if (ctxt->instate != XML_PARSER_EOF)
- ctxt->input->cur = in + 1;
+ ctxt->input->cur = in + 1;
return;
}
in++;
@@ -4669,8 +4862,6 @@ xmlParseCharDataInternal(xmlParserCtxtPtr ctxt, int partial) {
line = ctxt->input->line;
col = ctxt->input->col;
}
- if (ctxt->instate == XML_PARSER_EOF)
- return;
}
ctxt->input->cur = in;
if (*in == 0xD) {
@@ -4691,8 +4882,6 @@ xmlParseCharDataInternal(xmlParserCtxtPtr ctxt, int partial) {
}
SHRINK;
GROW;
- if (ctxt->instate == XML_PARSER_EOF)
- return;
in = ctxt->input->cur;
} while (((*in >= 0x20) && (*in <= 0x7F)) ||
(*in == 0x09) || (*in == 0x0a));
@@ -4749,15 +4938,10 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int partial) {
}
}
nbchar = 0;
- /* something really bad happened in the SAX callback */
- if (ctxt->instate != XML_PARSER_CONTENT)
- return;
SHRINK;
}
cur = CUR_CHAR(l);
}
- if (ctxt->instate == XML_PARSER_EOF)
- return;
if (nbchar != 0) {
buf[nbchar] = 0;
/*
@@ -4779,9 +4963,8 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int partial) {
/*
* cur == 0 can mean
*
- * - XML_PARSER_EOF or memory error. This is checked above.
- * - An actual 0 character.
* - End of buffer.
+ * - An actual 0 character.
* - An incomplete UTF-8 sequence. This is allowed if partial is set.
*/
if (ctxt->input->cur < ctxt->input->end) {
@@ -4910,16 +5093,13 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
XML_MAX_HUGE_LENGTH :
XML_MAX_TEXT_LENGTH;
- int inputid;
-
- inputid = ctxt->input->id;
if (buf == NULL) {
len = 0;
size = XML_PARSER_BUFFER_SIZE;
buf = (xmlChar *) xmlMallocAtomic(size);
if (buf == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return;
}
}
@@ -4962,7 +5142,7 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
new_buf = (xmlChar *) xmlRealloc(buf, new_size);
if (new_buf == NULL) {
xmlFree (buf);
- xmlErrMemory(ctxt, NULL);
+ xmlErrMemory(ctxt);
return;
}
buf = new_buf;
@@ -4986,10 +5166,6 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
}
buf[len] = 0;
- if (ctxt->instate == XML_PARSER_EOF) {
- xmlFree(buf);
- return;
- }
if (cur == 0) {
xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
"Comment not terminated \n", 3)))
goto done;
xmlParseComment(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_CONTENT;
break;
}
@@ -11874,8 +11283,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
else
xmlParseEndTag1(ctxt, 0);
#endif /* LIBXML_SAX1_ENABLED */
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
if (ctxt->nameNr == 0) {
ctxt->instate = XML_PARSER_EPILOG;
} else {
@@ -11927,8 +11334,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
ctxt->sax->characters(ctxt->userData,
ctxt->input->cur, tmp);
}
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
SKIPL(tmp);
} else {
int base = term - CUR_PTR;
@@ -11962,8 +11367,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
ctxt->sax->characters(ctxt->userData,
ctxt->input->cur, base);
}
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
SKIPL(base + 3);
ctxt->instate = XML_PARSER_CONTENT;
}
@@ -11985,8 +11388,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
(!xmlParseLookupString(ctxt, 2, "?>", 2)))
goto done;
xmlParsePI(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
break;
} else if (next == '!') {
if ((!terminate) && (avail < 3))
@@ -12000,8 +11401,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
(!xmlParseLookupString(ctxt, 4, "-->", 3)))
goto done;
xmlParseComment(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
break;
}
} else if (ctxt->instate == XML_PARSER_MISC) {
@@ -12018,8 +11417,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
goto done;
ctxt->inSubset = 1;
xmlParseDocTypeDecl(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
if (RAW == '[') {
ctxt->instate = XML_PARSER_DTD;
} else {
@@ -12037,8 +11434,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
ctxt->extSubURI);
ctxt->inSubset = 0;
xmlCleanSpecialAttr(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_PROLOG;
}
break;
@@ -12051,8 +11446,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
if (ctxt->errNo == XML_ERR_OK)
xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
ctxt->instate = XML_PARSER_EOF;
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
+ xmlFinishDocument(ctxt);
} else {
ctxt->instate = XML_PARSER_START_TAG;
}
@@ -12061,8 +11455,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
if ((!terminate) && (!xmlParseLookupInternalSubset(ctxt)))
goto done;
xmlParseInternalSubset(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->inSubset = 2;
if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
(ctxt->sax->externalSubset != NULL))
@@ -12070,13 +11462,11 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
ctxt->extSubSystem, ctxt->extSubURI);
ctxt->inSubset = 0;
xmlCleanSpecialAttr(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- goto done;
ctxt->instate = XML_PARSER_PROLOG;
break;
}
default:
- xmlGenericError(xmlGenericErrorContext,
+ xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
"PP: internal error\n");
ctxt->instate = XML_PARSER_EOF;
break;
@@ -12085,19 +11475,10 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
done:
return(ret);
encoding_error:
- if (ctxt->input->end - ctxt->input->cur < 4) {
- __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
- "Input is not proper UTF-8, indicate encoding !\n",
- NULL, NULL);
- } else {
- char buffer[150];
-
- snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- ctxt->input->cur[0], ctxt->input->cur[1],
- ctxt->input->cur[2], ctxt->input->cur[3]);
- __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
- "Input is not proper UTF-8, indicate encoding !\n%s",
- BAD_CAST buffer, NULL);
+ /* Only report the first error */
+ if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
+ xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
+ ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
}
return(0);
}
@@ -12105,31 +11486,42 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
/**
* xmlParseChunk:
* @ctxt: an XML parser context
- * @chunk: an char array
- * @size: the size in byte of the chunk
+ * @chunk: chunk of memory
+ * @size: size of chunk in bytes
* @terminate: last chunk indicator
*
- * Parse a Chunk of memory
+ * Parse a chunk of memory in push parser mode.
+ *
+ * Assumes that the parser context was initialized with
+ * xmlCreatePushParserCtxt.
+ *
+ * The last chunk, which will often be empty, must be marked with
+ * the @terminate flag. With the default SAX callbacks, the resulting
+ * document will be available in ctxt->myDoc. This pointer will not
+ * be freed by the library.
*
- * Returns zero if no error, the xmlParserErrors otherwise.
+ * If the document isn't well-formed, ctxt->myDoc is set to NULL.
+ * The push parser doesn't support recovery mode.
+ *
+ * Returns an xmlParserErrors code (0 on success).
*/
int
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
int terminate) {
+ size_t curBase;
+ size_t maxLength;
int end_in_lf = 0;
- if (ctxt == NULL)
- return(XML_ERR_INTERNAL_ERROR);
- if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+ if ((ctxt == NULL) || (size < 0))
+ return(XML_ERR_ARGUMENT);
+ if (ctxt->disableSAX != 0)
return(ctxt->errNo);
- if (ctxt->instate == XML_PARSER_EOF)
- return(-1);
if (ctxt->input == NULL)
- return(-1);
+ return(XML_ERR_INTERNAL_ERROR);
- ctxt->progressive = 1;
+ ctxt->input->flags |= XML_INPUT_PROGRESSIVE;
if (ctxt->instate == XML_PARSER_START)
- xmlDetectSAX2(ctxt);
+ xmlCtxtInitializeLate(ctxt);
if ((size > 0) && (chunk != NULL) && (!terminate) &&
(chunk[size - 1] == '\r')) {
end_in_lf = 1;
@@ -12137,30 +11529,31 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
}
if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
+ (ctxt->input->buf != NULL)) {
size_t pos = ctxt->input->cur - ctxt->input->base;
int res;
res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
if (res < 0) {
- xmlFatalErr(ctxt, ctxt->input->buf->error, NULL);
+ xmlCtxtErrIO(ctxt, ctxt->input->buf->error, NULL);
xmlHaltParser(ctxt);
return(ctxt->errNo);
}
}
xmlParseTryOrFinish(ctxt, terminate);
- if (ctxt->instate == XML_PARSER_EOF)
- return(ctxt->errNo);
- if ((ctxt->input != NULL) &&
- (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
- ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
- xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
+ curBase = ctxt->input->cur - ctxt->input->base;
+ maxLength = (ctxt->options & XML_PARSE_HUGE) ?
+ XML_MAX_HUGE_LENGTH :
+ XML_MAX_LOOKUP_LIMIT;
+ if (curBase > maxLength) {
+ xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT,
+ "Buffer size limit exceeded, try XML_PARSE_HUGE\n");
xmlHaltParser(ctxt);
}
+
if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
return(ctxt->errNo);
@@ -12172,7 +11565,7 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
res = xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
if (res < 0) {
- xmlFatalErr(ctxt, ctxt->input->buf->error, NULL);
+ xmlCtxtErrIO(ctxt, ctxt->input->buf->error, NULL);
xmlHaltParser(ctxt);
return(ctxt->errNo);
}
@@ -12197,15 +11590,15 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
}
} else if ((ctxt->input->buf != NULL) &&
(ctxt->input->buf->encoder != NULL) &&
+ (ctxt->input->buf->error == 0) &&
(!xmlBufIsEmpty(ctxt->input->buf->raw))) {
xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
"Truncated multi-byte sequence at EOF\n");
}
if (ctxt->instate != XML_PARSER_EOF) {
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
+ ctxt->instate = XML_PARSER_EOF;
+ xmlFinishDocument(ctxt);
}
- ctxt->instate = XML_PARSER_EOF;
}
if (ctxt->wellFormed == 0)
return((xmlParserErrors) ctxt->errNo);
@@ -12221,81 +11614,42 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
/**
* xmlCreatePushParserCtxt:
- * @sax: a SAX handler
- * @user_data: The user data returned on SAX callbacks
- * @chunk: a pointer to an array of chars
- * @size: number of chars in the array
- * @filename: an optional file name or URI
+ * @sax: a SAX handler (optional)
+ * @user_data: user data for SAX callbacks (optional)
+ * @chunk: initial chunk (optional, deprecated)
+ * @size: size of initial chunk in bytes
+ * @filename: file name or URI (optional)
*
* Create a parser context for using the XML parser in push mode.
- * If @buffer and @size are non-NULL, the data is used to detect
- * the encoding. The remaining characters will be parsed so they
- * don't need to be fed in again through xmlParseChunk.
- * To allow content encoding detection, @size should be >= 4
- * The value of @filename is used for fetching external entities
- * and error/warning reports.
+ * See xmlParseChunk.
*
- * Returns the new parser context or NULL
+ * Passing an initial chunk is useless and deprecated.
+ *
+ * @filename is used as base URI to fetch external entities and for
+ * error reports.
+ *
+ * Returns the new parser context or NULL in case of error.
*/
xmlParserCtxtPtr
xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
const char *chunk, int size, const char *filename) {
xmlParserCtxtPtr ctxt;
- xmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
-
- buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
- if (buf == NULL) return(NULL);
+ xmlParserInputPtr input;
ctxt = xmlNewSAXParserCtxt(sax, user_data);
- if (ctxt == NULL) {
- xmlErrMemory(NULL, "creating parser: out of memory\n");
- xmlFreeParserInputBuffer(buf);
+ if (ctxt == NULL)
return(NULL);
- }
+
+ ctxt->options &= ~XML_PARSE_NODICT;
ctxt->dictNames = 1;
- if (filename == NULL) {
- ctxt->directory = NULL;
- } else {
- ctxt->directory = xmlParserGetDirectory(filename);
- }
- inputStream = xmlNewInputStream(ctxt);
- if (inputStream == NULL) {
+ input = xmlNewInputPush(ctxt, filename, chunk, size, NULL);
+ if (input == NULL) {
xmlFreeParserCtxt(ctxt);
- xmlFreeParserInputBuffer(buf);
return(NULL);
}
-
- if (filename == NULL)
- inputStream->filename = NULL;
- else {
- inputStream->filename = (char *)
- xmlCanonicPath((const xmlChar *) filename);
- if (inputStream->filename == NULL) {
- xmlFreeInputStream(inputStream);
- xmlFreeParserCtxt(ctxt);
- xmlFreeParserInputBuffer(buf);
- return(NULL);
- }
- }
- inputStream->buf = buf;
- xmlBufResetInput(inputStream->buf->buffer, inputStream);
- inputPush(ctxt, inputStream);
-
- if ((size != 0) && (chunk != NULL) &&
- (ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
- size_t pos = ctxt->input->cur - ctxt->input->base;
- int res;
-
- res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
- xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
- if (res < 0) {
- xmlFatalErr(ctxt, ctxt->input->buf->error, NULL);
- xmlHaltParser(ctxt);
- }
- }
+ inputPush(ctxt, input);
return(ctxt);
}
@@ -12312,17 +11666,18 @@ xmlStopParser(xmlParserCtxtPtr ctxt) {
if (ctxt == NULL)
return;
xmlHaltParser(ctxt);
- ctxt->errNo = XML_ERR_USER_STOP;
+ if (ctxt->errNo != XML_ERR_NO_MEMORY)
+ ctxt->errNo = XML_ERR_USER_STOP;
}
/**
* xmlCreateIOParserCtxt:
- * @sax: a SAX handler
- * @user_data: The user data returned on SAX callbacks
+ * @sax: a SAX handler (optional)
+ * @user_data: user data for SAX callbacks (optional)
* @ioread: an I/O read function
- * @ioclose: an I/O close function
+ * @ioclose: an I/O close function (optional)
* @ioctx: an I/O handler
- * @enc: the charset encoding if known
+ * @enc: the charset encoding if known (deprecated)
*
* Create a parser context for using the XML parser with an existing
* I/O stream
@@ -12331,33 +11686,24 @@ xmlStopParser(xmlParserCtxtPtr ctxt) {
*/
xmlParserCtxtPtr
xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
- xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
- void *ioctx, xmlCharEncoding enc) {
+ xmlInputReadCallback ioread,
+ xmlInputCloseCallback ioclose,
+ void *ioctx, xmlCharEncoding enc) {
xmlParserCtxtPtr ctxt;
- xmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
-
- if (ioread == NULL) return(NULL);
-
- buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
- if (buf == NULL) {
- if (ioclose != NULL)
- ioclose(ioctx);
- return (NULL);
- }
+ xmlParserInputPtr input;
+ const char *encoding;
ctxt = xmlNewSAXParserCtxt(sax, user_data);
- if (ctxt == NULL) {
- xmlFreeParserInputBuffer(buf);
+ if (ctxt == NULL)
return(NULL);
- }
- inputStream = xmlNewIOInputStream(ctxt, buf, enc);
- if (inputStream == NULL) {
+ encoding = xmlGetCharEncodingName(enc);
+ input = xmlNewInputIO(ctxt, NULL, ioread, ioclose, ioctx, encoding, 0);
+ if (input == NULL) {
xmlFreeParserCtxt(ctxt);
- return(NULL);
+ return (NULL);
}
- inputPush(ctxt, inputStream);
+ inputPush(ctxt, input);
return(ctxt);
}
@@ -12397,11 +11743,6 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
return(NULL);
}
- /* We are loading a DTD */
- ctxt->options |= XML_PARSE_DTDLOAD;
-
- xmlDetectSAX2(ctxt);
-
/*
* generate a parser input from the I/O handler
*/
@@ -12427,18 +11768,15 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
/*
* let's parse that entity knowing it's an external subset.
*/
- ctxt->inSubset = 2;
ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
if (ctxt->myDoc == NULL) {
- xmlErrMemory(ctxt, "New Doc failed");
+ xmlErrMemory(ctxt);
return(NULL);
}
ctxt->myDoc->properties = XML_DOC_INTERNAL;
ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
BAD_CAST "none", BAD_CAST "none");
- xmlDetectEncoding(ctxt);
-
xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
if (ctxt->myDoc != NULL) {
@@ -12494,9 +11832,6 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
return(NULL);
}
- /* We are loading a DTD */
- ctxt->options |= XML_PARSE_DTDLOAD;
-
/*
* Canonicalise the system ID
*/
@@ -12540,16 +11875,20 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
/*
* let's parse that entity knowing it's an external subset.
*/
- ctxt->inSubset = 2;
ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
if (ctxt->myDoc == NULL) {
- xmlErrMemory(ctxt, "New Doc failed");
+ xmlErrMemory(ctxt);
xmlFreeParserCtxt(ctxt);
return(NULL);
}
ctxt->myDoc->properties = XML_DOC_INTERNAL;
ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
ExternalID, SystemID);
+ if (ctxt->myDoc->extSubset == NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
+ }
xmlParseExternalSubset(ctxt, ExternalID, SystemID);
if (ctxt->myDoc != NULL) {
@@ -12600,258 +11939,246 @@ xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
* *
************************************************************************/
-/**
- * xmlParseCtxtExternalEntity:
- * @ctx: the existing parsing context
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @lst: the return value for the set of parsed nodes
- *
- * Parse an external general entity within an existing parsing context
- * An external general parsed entity is well-formed if it matches the
- * production labeled extParsedEnt.
- *
- * [78] extParsedEnt ::= TextDecl? content
- *
- * Returns 0 if the entity is well formed, -1 in case of args problem and
- * the parser error code otherwise
- */
+static xmlNodePtr
+xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
+ int hasTextDecl, int buildTree) {
+ xmlNodePtr root = NULL;
+ xmlNodePtr list = NULL;
+ xmlChar *rootName = BAD_CAST "#root";
+ int result;
-int
-xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
- const xmlChar *ID, xmlNodePtr *lst) {
- void *userData;
+ if (buildTree) {
+ root = xmlNewDocNode(ctxt->myDoc, NULL, rootName, NULL);
+ if (root == NULL) {
+ xmlErrMemory(ctxt);
+ goto error;
+ }
+ }
- if (ctx == NULL) return(-1);
- /*
- * If the user provided their own SAX callbacks, then reuse the
- * userData callback field, otherwise the expected setup in a
- * DOM builder is to have userData == ctxt
- */
- if (ctx->userData == ctx)
- userData = NULL;
- else
- userData = ctx->userData;
- return xmlParseExternalEntityPrivate(ctx->myDoc, ctx, ctx->sax,
- userData, ctx->depth + 1,
- URL, ID, lst);
-}
+ if (xmlPushInput(ctxt, input) < 0)
+ goto error;
-/**
- * xmlParseExternalEntityPrivate:
- * @doc: the document the chunk pertains to
- * @oldctxt: the previous parser context if available
- * @sax: the SAX handler block (possibly NULL)
- * @user_data: The user data returned on SAX callbacks (possibly NULL)
- * @depth: Used for loop detection, use 0
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @list: the return value for the set of parsed nodes
- *
- * Private version of xmlParseExternalEntity()
- *
- * Returns 0 if the entity is well formed, -1 in case of args problem and
- * the parser error code otherwise
- */
+ nameNsPush(ctxt, rootName, NULL, NULL, 0, 0);
+ spacePush(ctxt, -1);
-static xmlParserErrors
-xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
- xmlSAXHandlerPtr sax,
- void *user_data, int depth, const xmlChar *URL,
- const xmlChar *ID, xmlNodePtr *list) {
- xmlParserCtxtPtr ctxt;
- xmlDocPtr newDoc;
- xmlNodePtr newRoot;
- xmlParserErrors ret = XML_ERR_OK;
+ if (buildTree)
+ nodePush(ctxt, root);
- if (((depth > 40) &&
- ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
- (depth > 100)) {
- xmlFatalErrMsg(oldctxt, XML_ERR_ENTITY_LOOP,
- "Maximum entity nesting depth exceeded");
- return(XML_ERR_ENTITY_LOOP);
+ if (hasTextDecl) {
+ xmlDetectEncoding(ctxt);
+
+ /*
+ * Parse a possible text declaration first
+ */
+ if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
+ (IS_BLANK_CH(NXT(5)))) {
+ xmlParseTextDecl(ctxt);
+ /*
+ * An XML-1.0 document can't reference an entity not XML-1.0
+ */
+ if ((xmlStrEqual(ctxt->version, BAD_CAST "1.0")) &&
+ (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
+ xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
+ "Version mismatch between document and "
+ "entity\n");
+ }
+ }
}
- if (list != NULL)
- *list = NULL;
- if ((URL == NULL) && (ID == NULL))
- return(XML_ERR_INTERNAL_ERROR);
- if (doc == NULL)
- return(XML_ERR_INTERNAL_ERROR);
+ xmlParseContentInternal(ctxt);
- ctxt = xmlCreateEntityParserCtxtInternal(sax, user_data, URL, ID, NULL,
- oldctxt);
- if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
- if (oldctxt != NULL) {
- ctxt->nbErrors = oldctxt->nbErrors;
- ctxt->nbWarnings = oldctxt->nbWarnings;
- }
- xmlDetectSAX2(ctxt);
+ if (ctxt->input->cur < ctxt->input->end)
+ xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
- newDoc = xmlNewDoc(BAD_CAST "1.0");
- if (newDoc == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(XML_ERR_INTERNAL_ERROR);
- }
- newDoc->properties = XML_DOC_INTERNAL;
- if (doc) {
- newDoc->intSubset = doc->intSubset;
- newDoc->extSubset = doc->extSubset;
- if (doc->dict) {
- newDoc->dict = doc->dict;
- xmlDictReference(newDoc->dict);
- }
- if (doc->URL != NULL) {
- newDoc->URL = xmlStrdup(doc->URL);
+ if ((ctxt->wellFormed) ||
+ ((ctxt->recovery) && (ctxt->errNo != XML_ERR_NO_MEMORY))) {
+ if (root != NULL) {
+ xmlNodePtr cur;
+
+ /*
+ * Return the newly created nodeset after unlinking it from
+ * its pseudo parent.
+ */
+ cur = root->children;
+ list = cur;
+ while (cur != NULL) {
+ cur->parent = NULL;
+ cur = cur->next;
+ }
+ root->children = NULL;
+ root->last = NULL;
}
}
- newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newRoot == NULL) {
- if (sax != NULL)
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
- return(XML_ERR_INTERNAL_ERROR);
- }
- xmlAddChild((xmlNodePtr) newDoc, newRoot);
- nodePush(ctxt, newDoc->children);
- if (doc == NULL) {
- ctxt->myDoc = newDoc;
- } else {
- ctxt->myDoc = doc;
- newRoot->doc = doc;
- }
- xmlDetectEncoding(ctxt);
+ /*
+ * Read the rest of the stream in case of errors. We want
+ * to account for the whole entity size.
+ */
+ do {
+ ctxt->input->cur = ctxt->input->end;
+ xmlParserShrink(ctxt);
+ result = xmlParserGrow(ctxt);
+ } while (result > 0);
+
+ if (buildTree)
+ nodePop(ctxt);
+
+ namePop(ctxt);
+ spacePop(ctxt);
+
+ /* xmlPopInput would free the stream */
+ inputPop(ctxt);
+
+error:
+ xmlFreeNode(root);
+
+ return(list);
+}
+
+static void
+xmlCtxtParseEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
+ xmlParserInputPtr input;
+ xmlNodePtr list;
+ unsigned long consumed;
+ int isExternal;
+ int buildTree;
+ int oldMinNsIndex;
+ int oldNodelen, oldNodemem;
+
+ isExternal = (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY);
+ buildTree = (ctxt->node != NULL);
/*
- * Parse a possible text declaration first
+ * Recursion check
*/
- if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
- xmlParseTextDecl(ctxt);
- /*
- * An XML-1.0 document can't reference an entity not XML-1.0
- */
- if ((xmlStrEqual(oldctxt->version, BAD_CAST "1.0")) &&
- (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
- xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
- "Version mismatch between document and entity\n");
- }
+ if (ent->flags & XML_ENT_EXPANDING) {
+ xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+ xmlHaltParser(ctxt);
+ goto error;
}
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->depth = depth;
- if (oldctxt != NULL) {
- ctxt->_private = oldctxt->_private;
- ctxt->loadsubset = oldctxt->loadsubset;
- ctxt->validate = oldctxt->validate;
- ctxt->valid = oldctxt->valid;
- ctxt->replaceEntities = oldctxt->replaceEntities;
- if (oldctxt->validate) {
- ctxt->vctxt.error = oldctxt->vctxt.error;
- ctxt->vctxt.warning = oldctxt->vctxt.warning;
- ctxt->vctxt.userData = oldctxt->vctxt.userData;
- ctxt->vctxt.flags = oldctxt->vctxt.flags;
- }
- ctxt->external = oldctxt->external;
- if (ctxt->dict) xmlDictFree(ctxt->dict);
- ctxt->dict = oldctxt->dict;
- ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
- ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
- ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
- ctxt->dictNames = oldctxt->dictNames;
- ctxt->attsDefault = oldctxt->attsDefault;
- ctxt->attsSpecial = oldctxt->attsSpecial;
- ctxt->linenumbers = oldctxt->linenumbers;
- ctxt->record_info = oldctxt->record_info;
- ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
- ctxt->node_seq.length = oldctxt->node_seq.length;
- ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
- } else {
- /*
- * Doing validity checking on chunk without context
- * doesn't make sense
- */
- ctxt->_private = NULL;
- ctxt->validate = 0;
- ctxt->external = 2;
- ctxt->loadsubset = 0;
- }
+ /*
+ * Load entity
+ */
+ input = xmlNewEntityInputStream(ctxt, ent);
+ if (input == NULL)
+ goto error;
- xmlParseContent(ctxt);
+ /*
+ * When building a tree, we need to limit the scope of namespace
+ * declarations, so that entities don't reference xmlNs structs
+ * from the parent of a reference.
+ */
+ oldMinNsIndex = ctxt->nsdb->minNsIndex;
+ if (buildTree)
+ ctxt->nsdb->minNsIndex = ctxt->nsNr;
- if ((RAW == '<') && (NXT(1) == '/')) {
- xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
- } else if (RAW != 0) {
- xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
- }
- if (ctxt->node != newDoc->children) {
- xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
- }
+ oldNodelen = ctxt->nodelen;
+ oldNodemem = ctxt->nodemem;
+ ctxt->nodelen = 0;
+ ctxt->nodemem = 0;
- if (!ctxt->wellFormed) {
- ret = (xmlParserErrors)ctxt->errNo;
- if (oldctxt != NULL) {
- oldctxt->errNo = ctxt->errNo;
- oldctxt->wellFormed = 0;
- xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
- }
- } else {
- if (list != NULL) {
- xmlNodePtr cur;
+ /*
+ * Parse content
+ *
+ * This initiates a recursive call chain:
+ *
+ * - xmlCtxtParseContent
+ * - xmlParseContentInternal
+ * - xmlParseReference
+ * - xmlCtxtParseEntity
+ *
+ * The nesting depth is limited by the maximum number of inputs,
+ * see xmlPushInput.
+ *
+ * It's possible to make this non-recursive (minNsIndex must be
+ * stored in the input struct) at the expense of code readability.
+ */
- /*
- * Return the newly created nodeset after unlinking it from
- * they pseudo parent.
- */
- cur = newDoc->children->children;
- *list = cur;
- while (cur != NULL) {
- cur->parent = NULL;
- cur = cur->next;
- }
- newDoc->children->children = NULL;
- }
- ret = XML_ERR_OK;
- }
+ ent->flags |= XML_ENT_EXPANDING;
+
+ list = xmlCtxtParseContent(ctxt, input, isExternal, buildTree);
+
+ ent->flags &= ~XML_ENT_EXPANDING;
+
+ ctxt->nsdb->minNsIndex = oldMinNsIndex;
+ ctxt->nodelen = oldNodelen;
+ ctxt->nodemem = oldNodemem;
/*
- * Also record the size of the entity parsed
+ * Entity size accounting
*/
- if (ctxt->input != NULL && oldctxt != NULL) {
- unsigned long consumed = ctxt->input->consumed;
+ consumed = input->consumed;
+ xmlSaturatedAddSizeT(&consumed, input->end - input->base);
- xmlSaturatedAddSizeT(&consumed, ctxt->input->cur - ctxt->input->base);
+ if ((ent->flags & XML_ENT_CHECKED) == 0)
+ xmlSaturatedAdd(&ent->expandedSize, consumed);
- xmlSaturatedAdd(&oldctxt->sizeentities, consumed);
- xmlSaturatedAdd(&oldctxt->sizeentities, ctxt->sizeentities);
+ if ((ent->flags & XML_ENT_PARSED) == 0) {
+ if (isExternal)
+ xmlSaturatedAdd(&ctxt->sizeentities, consumed);
- xmlSaturatedAdd(&oldctxt->sizeentcopy, consumed);
- xmlSaturatedAdd(&oldctxt->sizeentcopy, ctxt->sizeentcopy);
+ ent->children = list;
+
+ while (list != NULL) {
+ list->parent = (xmlNodePtr) ent;
+ if (list->next == NULL)
+ ent->last = list;
+ list = list->next;
+ }
+ } else {
+ xmlFreeNodeList(list);
}
- if (oldctxt != NULL) {
- ctxt->dict = NULL;
- ctxt->attsDefault = NULL;
- ctxt->attsSpecial = NULL;
- oldctxt->nbErrors = ctxt->nbErrors;
- oldctxt->nbWarnings = ctxt->nbWarnings;
- oldctxt->validate = ctxt->validate;
- oldctxt->valid = ctxt->valid;
- oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
- oldctxt->node_seq.length = ctxt->node_seq.length;
- oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
- }
- ctxt->node_seq.maximum = 0;
- ctxt->node_seq.length = 0;
- ctxt->node_seq.buffer = NULL;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
+ xmlFreeInputStream(input);
+
+error:
+ ent->flags |= XML_ENT_PARSED | XML_ENT_CHECKED;
+}
+
+/**
+ * xmlParseCtxtExternalEntity:
+ * @ctxt: the existing parsing context
+ * @URL: the URL for the entity to load
+ * @ID: the System ID for the entity to load
+ * @listOut: the return value for the set of parsed nodes
+ *
+ * Parse an external general entity within an existing parsing context
+ * An external general parsed entity is well-formed if it matches the
+ * production labeled extParsedEnt.
+ *
+ * [78] extParsedEnt ::= TextDecl? content
+ *
+ * Returns 0 if the entity is well formed, -1 in case of args problem and
+ * the parser error code otherwise
+ */
+
+int
+xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *URL,
+ const xmlChar *ID, xmlNodePtr *listOut) {
+ xmlParserInputPtr input;
+ xmlNodePtr list;
+
+ if (listOut != NULL)
+ *listOut = NULL;
+
+ if (ctxt == NULL)
+ return(XML_ERR_ARGUMENT);
+
+ input = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
+ if (input == NULL)
+ return(ctxt->errNo);
+
+ xmlCtxtInitializeLate(ctxt);
- return(ret);
+ list = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 1, 1);
+ if (listOut != NULL)
+ *listOut = list;
+ else
+ xmlFreeNodeList(list);
+
+ xmlFreeInputStream(input);
+ return(ctxt->errNo);
}
#ifdef LIBXML_SAX1_ENABLED
@@ -12863,7 +12190,9 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
* @depth: Used for loop detection, use 0
* @URL: the URL for the entity to load
* @ID: the System ID for the entity to load
- * @lst: the return value for the set of parsed nodes
+ * @list: the return value for the set of parsed nodes
+ *
+ * DEPRECATED: Use xmlParseCtxtExternalEntity.
*
* Parse an external general entity
* An external general parsed entity is well-formed if it matches the
@@ -12877,9 +12206,26 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
int
xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
- int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
- return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
- ID, lst));
+ int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *list) {
+ xmlParserCtxtPtr ctxt;
+ int ret;
+
+ if (list != NULL)
+ *list = NULL;
+
+ if (doc == NULL)
+ return(XML_ERR_ARGUMENT);
+
+ ctxt = xmlNewSAXParserCtxt(sax, user_data);
+ if (ctxt == NULL)
+ return(XML_ERR_NO_MEMORY);
+
+ ctxt->depth = depth;
+ ctxt->myDoc = doc;
+ ret = xmlParseCtxtExternalEntity(ctxt, URL, ID, list);
+
+ xmlFreeParserCtxt(ctxt);
+ return(ret);
}
/**
@@ -12910,229 +12256,6 @@ xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
}
#endif /* LIBXML_SAX1_ENABLED */
-/**
- * xmlParseBalancedChunkMemoryInternal:
- * @oldctxt: the existing parsing context
- * @string: the input string in UTF8 or ISO-Latin (zero terminated)
- * @user_data: the user data field for the parser context
- * @lst: the return value for the set of parsed nodes
- *
- *
- * Parse a well-balanced chunk of an XML document
- * called by the parser
- * The allowed sequence for the Well Balanced Chunk is the one defined by
- * the content production in the XML grammar:
- *
- * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
- *
- * Returns XML_ERR_OK if the chunk is well balanced, and the parser
- * error code otherwise
- *
- * In case recover is set to 1, the nodelist will not be empty even if
- * the parsed chunk is not well balanced.
- */
-static xmlParserErrors
-xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
- const xmlChar *string, void *user_data, xmlNodePtr *lst) {
- xmlParserCtxtPtr ctxt;
- xmlDocPtr newDoc = NULL;
- xmlNodePtr newRoot;
- xmlSAXHandlerPtr oldsax = NULL;
- xmlNodePtr content = NULL;
- xmlNodePtr last = NULL;
- xmlParserErrors ret = XML_ERR_OK;
- xmlHashedString hprefix, huri;
- unsigned i;
-
- if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
- (oldctxt->depth > 100)) {
- xmlFatalErrMsg(oldctxt, XML_ERR_ENTITY_LOOP,
- "Maximum entity nesting depth exceeded");
- return(XML_ERR_ENTITY_LOOP);
- }
-
-
- if (lst != NULL)
- *lst = NULL;
- if (string == NULL)
- return(XML_ERR_INTERNAL_ERROR);
-
- ctxt = xmlCreateDocParserCtxt(string);
- if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
- ctxt->nbErrors = oldctxt->nbErrors;
- ctxt->nbWarnings = oldctxt->nbWarnings;
- if (user_data != NULL)
- ctxt->userData = user_data;
- else
- ctxt->userData = ctxt;
- if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
- ctxt->dict = oldctxt->dict;
- ctxt->input_id = oldctxt->input_id;
- ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
- ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
- ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
-
- /*
- * Propagate namespaces down the entity
- *
- * Making entities and namespaces work correctly requires additional
- * changes, see xmlParseReference.
- */
-
- /* Default namespace */
- hprefix.name = NULL;
- hprefix.hashValue = 0;
- huri.name = xmlParserNsLookupUri(oldctxt, &hprefix);
- huri.hashValue = 0;
- if (huri.name != NULL)
- xmlParserNsPush(ctxt, NULL, &huri, NULL, 0);
-
- for (i = 0; i < oldctxt->nsdb->hashSize; i++) {
- xmlParserNsBucket *bucket = &oldctxt->nsdb->hash[i];
- const xmlChar **ns;
- xmlParserNsExtra *extra;
- unsigned nsIndex;
-
- if ((bucket->hashValue != 0) &&
- (bucket->index != INT_MAX)) {
- nsIndex = bucket->index;
- ns = &oldctxt->nsTab[nsIndex * 2];
- extra = &oldctxt->nsdb->extra[nsIndex];
-
- hprefix.name = ns[0];
- hprefix.hashValue = bucket->hashValue;
- huri.name = ns[1];
- huri.hashValue = extra->uriHashValue;
- /*
- * Don't copy SAX data to avoid a use-after-free with XML reader.
- * This matches the pre-2.12 behavior.
- */
- xmlParserNsPush(ctxt, &hprefix, &huri, NULL, 0);
- }
- }
-
- oldsax = ctxt->sax;
- ctxt->sax = oldctxt->sax;
- xmlDetectSAX2(ctxt);
- ctxt->replaceEntities = oldctxt->replaceEntities;
- ctxt->options = oldctxt->options;
-
- ctxt->_private = oldctxt->_private;
- if (oldctxt->myDoc == NULL) {
- newDoc = xmlNewDoc(BAD_CAST "1.0");
- if (newDoc == NULL) {
- ret = XML_ERR_INTERNAL_ERROR;
- goto error;
- }
- newDoc->properties = XML_DOC_INTERNAL;
- newDoc->dict = ctxt->dict;
- xmlDictReference(newDoc->dict);
- ctxt->myDoc = newDoc;
- } else {
- ctxt->myDoc = oldctxt->myDoc;
- content = ctxt->myDoc->children;
- last = ctxt->myDoc->last;
- }
- newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newRoot == NULL) {
- ret = XML_ERR_INTERNAL_ERROR;
- goto error;
- }
- ctxt->myDoc->children = NULL;
- ctxt->myDoc->last = NULL;
- xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
- nodePush(ctxt, ctxt->myDoc->children);
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->depth = oldctxt->depth;
-
- ctxt->validate = 0;
- ctxt->loadsubset = oldctxt->loadsubset;
- if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
- /*
- * ID/IDREF registration will be done in xmlValidateElement below
- */
- ctxt->loadsubset |= XML_SKIP_IDS;
- }
- ctxt->dictNames = oldctxt->dictNames;
- ctxt->attsDefault = oldctxt->attsDefault;
- ctxt->attsSpecial = oldctxt->attsSpecial;
-
- xmlParseContent(ctxt);
- if ((RAW == '<') && (NXT(1) == '/')) {
- xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
- } else if (RAW != 0) {
- xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
- }
- if (ctxt->node != ctxt->myDoc->children) {
- xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
- }
-
- if (!ctxt->wellFormed) {
- ret = (xmlParserErrors)ctxt->errNo;
- oldctxt->errNo = ctxt->errNo;
- oldctxt->wellFormed = 0;
- xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
- } else {
- ret = XML_ERR_OK;
- }
-
- if ((lst != NULL) && (ret == XML_ERR_OK)) {
- xmlNodePtr cur;
-
- /*
- * Return the newly created nodeset after unlinking it from
- * they pseudo parent.
- */
- cur = ctxt->myDoc->children->children;
- *lst = cur;
- while (cur != NULL) {
-#ifdef LIBXML_VALID_ENABLED
- if ((oldctxt->validate) && (oldctxt->wellFormed) &&
- (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
- (cur->type == XML_ELEMENT_NODE)) {
- oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
- oldctxt->myDoc, cur);
- }
-#endif /* LIBXML_VALID_ENABLED */
- cur->parent = NULL;
- cur = cur->next;
- }
- ctxt->myDoc->children->children = NULL;
- }
- if (ctxt->myDoc != NULL) {
- xmlFreeNode(ctxt->myDoc->children);
- ctxt->myDoc->children = content;
- ctxt->myDoc->last = last;
- }
-
- /*
- * Also record the size of the entity parsed
- */
- if (ctxt->input != NULL && oldctxt != NULL) {
- unsigned long consumed = ctxt->input->consumed;
-
- xmlSaturatedAddSizeT(&consumed, ctxt->input->cur - ctxt->input->base);
-
- xmlSaturatedAdd(&oldctxt->sizeentcopy, consumed);
- xmlSaturatedAdd(&oldctxt->sizeentcopy, ctxt->sizeentcopy);
- }
-
- oldctxt->nbErrors = ctxt->nbErrors;
- oldctxt->nbWarnings = ctxt->nbWarnings;
-
-error:
- ctxt->sax = oldsax;
- ctxt->dict = NULL;
- ctxt->attsDefault = NULL;
- ctxt->attsSpecial = NULL;
- xmlFreeParserCtxt(ctxt);
- if (newDoc != NULL) {
- xmlFreeDoc(newDoc);
- }
-
- return(ret);
-}
-
/**
* xmlParseInNodeContext:
* @node: the context node
@@ -13166,7 +12289,7 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
* check all input parameters, grab the document
*/
if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
- return(XML_ERR_INTERNAL_ERROR);
+ return(XML_ERR_ARGUMENT);
switch (node->type) {
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
@@ -13219,33 +12342,30 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
/*
* Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
- * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
+ * We need a dictionary for xmlCtxtInitializeLate, so if there's no doc dict
* we must wait until the last moment to free the original one.
*/
if (doc->dict != NULL) {
if (ctxt->dict != NULL)
xmlDictFree(ctxt->dict);
ctxt->dict = doc->dict;
- } else
+ } else {
options |= XML_PARSE_NODICT;
-
- if (doc->encoding != NULL) {
- xmlCharEncodingHandlerPtr hdlr;
-
- hdlr = xmlFindCharEncodingHandler((const char *) doc->encoding);
- if (hdlr != NULL) {
- xmlSwitchToEncoding(ctxt, hdlr);
- } else {
- return(XML_ERR_UNSUPPORTED_ENCODING);
- }
+ ctxt->dictNames = 0;
}
- xmlCtxtUseOptionsInternal(ctxt, options);
- xmlDetectSAX2(ctxt);
+ if (doc->encoding != NULL)
+ xmlSwitchEncodingName(ctxt, (const char *) doc->encoding);
+
+ xmlCtxtUseOptions(ctxt, options);
+ xmlCtxtInitializeLate(ctxt);
ctxt->myDoc = doc;
/* parsing in context, i.e. as within existing content */
ctxt->input_id = 2;
- ctxt->instate = XML_PARSER_CONTENT;
+
+ /*
+ * TODO: Use xmlCtxtParseContent
+ */
fake = xmlNewDocComment(node->doc, NULL);
if (fake == NULL) {
@@ -13289,26 +12409,18 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
__htmlParseContent(ctxt);
else
#endif
- xmlParseContent(ctxt);
+ xmlParseContentInternal(ctxt);
- xmlParserNsPop(ctxt, nsnr);
- if ((RAW == '<') && (NXT(1) == '/')) {
- xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
- } else if (RAW != 0) {
- xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
- }
- if ((ctxt->node != NULL) && (ctxt->node != node)) {
+ if (ctxt->input->cur < ctxt->input->end)
xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
- ctxt->wellFormed = 0;
- }
- if (!ctxt->wellFormed) {
- if (ctxt->errNo == 0)
- ret = XML_ERR_INTERNAL_ERROR;
- else
- ret = (xmlParserErrors)ctxt->errNo;
- } else {
+ xmlParserNsPop(ctxt, nsnr);
+
+ if ((ctxt->wellFormed) ||
+ ((ctxt->recovery) && (ctxt->errNo != XML_ERR_NO_MEMORY))) {
ret = XML_ERR_OK;
+ } else {
+ ret = (xmlParserErrors) ctxt->errNo;
}
/*
@@ -13355,19 +12467,18 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
* @user_data: The user data returned on SAX callbacks (possibly NULL)
* @depth: Used for loop detection, use 0
* @string: the input string in UTF8 or ISO-Latin (zero terminated)
- * @lst: the return value for the set of parsed nodes
+ * @listOut: the return value for the set of parsed nodes
* @recover: return nodes even if the data is broken (use 0)
*
- *
* Parse a well-balanced chunk of an XML document
- * called by the parser
+ *
* The allowed sequence for the Well Balanced Chunk is the one defined by
* the content production in the XML grammar:
*
* [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
*
- * Returns 0 if the chunk is well balanced, -1 in case of args problem and
- * the parser error code otherwise
+ * Returns 0 if the chunk is well balanced, or thehe parser error code
+ * otherwise.
*
* In case recover is set to 1, the nodelist will not be empty even if
* the parsed chunk is not well balanced, assuming the parsing succeeded to
@@ -13375,142 +12486,46 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
*/
int
xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
- void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
+ void *user_data, int depth, const xmlChar *string, xmlNodePtr *listOut,
int recover) {
xmlParserCtxtPtr ctxt;
- xmlDocPtr newDoc;
- xmlSAXHandlerPtr oldsax = NULL;
- xmlNodePtr content, newRoot;
- int ret = 0;
-
- if (depth > 40) {
- return(XML_ERR_ENTITY_LOOP);
- }
+ xmlParserInputPtr input;
+ xmlNodePtr list;
+ int ret;
+ if (listOut != NULL)
+ *listOut = NULL;
- if (lst != NULL)
- *lst = NULL;
if (string == NULL)
- return(-1);
+ return(XML_ERR_ARGUMENT);
- ctxt = xmlCreateDocParserCtxt(string);
- if (ctxt == NULL) return(-1);
- ctxt->userData = ctxt;
- if (sax != NULL) {
- oldsax = ctxt->sax;
- ctxt->sax = sax;
- if (user_data != NULL)
- ctxt->userData = user_data;
- }
- newDoc = xmlNewDoc(BAD_CAST "1.0");
- if (newDoc == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(-1);
- }
- newDoc->properties = XML_DOC_INTERNAL;
- if ((doc != NULL) && (doc->dict != NULL)) {
- xmlDictFree(ctxt->dict);
- ctxt->dict = doc->dict;
- xmlDictReference(ctxt->dict);
- ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
- ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
- ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
- ctxt->dictNames = 1;
- newDoc->dict = ctxt->dict;
- xmlDictReference(newDoc->dict);
- } else {
- xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT);
- }
- /* doc == NULL is only supported for historic reasons */
- if (doc != NULL) {
- newDoc->intSubset = doc->intSubset;
- newDoc->extSubset = doc->extSubset;
- }
- newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newRoot == NULL) {
- if (sax != NULL)
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
- return(-1);
- }
- xmlAddChild((xmlNodePtr) newDoc, newRoot);
- nodePush(ctxt, newRoot);
- /* doc == NULL is only supported for historic reasons */
- if (doc == NULL) {
- ctxt->myDoc = newDoc;
- } else {
- ctxt->myDoc = newDoc;
- /* Ensure that doc has XML spec namespace */
- xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
- newDoc->oldNs = doc->oldNs;
- }
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->input_id = 2;
- ctxt->depth = depth;
+ ctxt = xmlNewSAXParserCtxt(sax, user_data);
+ if (ctxt == NULL)
+ return(XML_ERR_NO_MEMORY);
- /*
- * Doing validity checking on chunk doesn't make sense
- */
- ctxt->validate = 0;
- ctxt->loadsubset = 0;
- xmlDetectSAX2(ctxt);
+ xmlCtxtInitializeLate(ctxt);
- if ( doc != NULL ){
- content = doc->children;
- doc->children = NULL;
- xmlParseContent(ctxt);
- doc->children = content;
- }
- else {
- xmlParseContent(ctxt);
- }
- if ((RAW == '<') && (NXT(1) == '/')) {
- xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
- } else if (RAW != 0) {
- xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
- }
- if (ctxt->node != newDoc->children) {
- xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+ ctxt->depth = depth;
+ ctxt->myDoc = doc;
+ if (recover) {
+ ctxt->options |= XML_PARSE_RECOVER;
+ ctxt->recovery = 1;
}
- if (!ctxt->wellFormed) {
- if (ctxt->errNo == 0)
- ret = 1;
- else
- ret = ctxt->errNo;
- } else {
- ret = 0;
- }
+ input = xmlNewStringInputStream(ctxt, string);
+ if (input == NULL)
+ return(ctxt->errNo);
- if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
- xmlNodePtr cur;
+ list = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 0, 1);
+ if (listOut != NULL)
+ *listOut = list;
+ else
+ xmlFreeNodeList(list);
- /*
- * Return the newly created nodeset after unlinking it from
- * they pseudo parent.
- */
- cur = newDoc->children->children;
- *lst = cur;
- while (cur != NULL) {
- xmlSetTreeDoc(cur, doc);
- cur->parent = NULL;
- cur = cur->next;
- }
- newDoc->children->children = NULL;
- }
+ ret = ctxt->errNo;
- if (sax != NULL)
- ctxt->sax = oldsax;
+ xmlFreeInputStream(input);
xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- /* This leaks the namespace list if doc == NULL */
- newDoc->oldNs = NULL;
- xmlFreeDoc(newDoc);
-
return(ret);
}
@@ -13542,117 +12557,47 @@ xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
return(NULL);
}
if (sax != NULL) {
- if (ctxt->sax != NULL)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
+ if (sax->initialized == XML_SAX2_MAGIC) {
+ *ctxt->sax = *sax;
+ } else {
+ memset(ctxt->sax, 0, sizeof(*ctxt->sax));
+ memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
+ }
ctxt->userData = NULL;
}
xmlParseExtParsedEnt(ctxt);
- if (ctxt->wellFormed)
+ if (ctxt->wellFormed) {
ret = ctxt->myDoc;
- else {
+ } else {
ret = NULL;
xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- if (sax != NULL)
- ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * xmlParseEntity:
- * @filename: the filename
- *
- * parse an XML external entity out of context and build a tree.
- *
- * [78] extParsedEnt ::= TextDecl? content
- *
- * This correspond to a "Well Balanced" chunk
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlParseEntity(const char *filename) {
- return(xmlSAXParseEntity(NULL, filename));
-}
-#endif /* LIBXML_SAX1_ENABLED */
-
-/**
- * xmlCreateEntityParserCtxtInternal:
- * @URL: the entity URL
- * @ID: the entity PUBLIC ID
- * @base: a possible base for the target URI
- * @pctx: parser context used to set options on new context
- *
- * Create a parser context for an external entity
- * Automatic support for ZLIB/Compress compressed document is provided
- * by default if found at compile-time.
- *
- * Returns the new parser context or NULL
- */
-static xmlParserCtxtPtr
-xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
- const xmlChar *URL, const xmlChar *ID, const xmlChar *base,
- xmlParserCtxtPtr pctx) {
- xmlParserCtxtPtr ctxt;
- xmlParserInputPtr inputStream;
- char *directory = NULL;
- xmlChar *uri;
-
- ctxt = xmlNewSAXParserCtxt(sax, userData);
- if (ctxt == NULL) {
- return(NULL);
- }
-
- if (pctx != NULL) {
- ctxt->options = pctx->options;
- ctxt->_private = pctx->_private;
- ctxt->input_id = pctx->input_id;
}
- /* Don't read from stdin. */
- if (xmlStrcmp(URL, BAD_CAST "-") == 0)
- URL = BAD_CAST "./-";
-
- uri = xmlBuildURI(URL, base);
-
- if (uri == NULL) {
- inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- inputPush(ctxt, inputStream);
-
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory((char *)URL);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
- } else {
- inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
- if (inputStream == NULL) {
- xmlFree(uri);
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
+ xmlFreeParserCtxt(ctxt);
- inputPush(ctxt, inputStream);
+ return(ret);
+}
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory((char *)uri);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
- xmlFree(uri);
- }
- return(ctxt);
+/**
+ * xmlParseEntity:
+ * @filename: the filename
+ *
+ * parse an XML external entity out of context and build a tree.
+ *
+ * [78] extParsedEnt ::= TextDecl? content
+ *
+ * This correspond to a "Well Balanced" chunk
+ *
+ * Returns the resulting document tree
+ */
+
+xmlDocPtr
+xmlParseEntity(const char *filename) {
+ return(xmlSAXParseEntity(NULL, filename));
}
+#endif /* LIBXML_SAX1_ENABLED */
/**
* xmlCreateEntityParserCtxt:
@@ -13660,6 +12605,8 @@ xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
* @ID: the entity PUBLIC ID
* @base: a possible base for the target URI
*
+ * DEPRECATED: Use xmlNewInputURL.
+ *
* Create a parser context for an external entity
* Automatic support for ZLIB/Compress compressed document is provided
* by default if found at compile-time.
@@ -13669,8 +12616,35 @@ xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
xmlParserCtxtPtr
xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
const xmlChar *base) {
- return xmlCreateEntityParserCtxtInternal(NULL, NULL, URL, ID, base, NULL);
+ xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
+ xmlChar *uri = NULL;
+
+ ctxt = xmlNewParserCtxt();
+ if (ctxt == NULL)
+ return(NULL);
+
+ if (base != NULL) {
+ if (xmlBuildURISafe(URL, base, &uri) < 0)
+ goto error;
+ if (uri != NULL)
+ URL = uri;
+ }
+ input = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
+ if (input == NULL)
+ goto error;
+
+ if (inputPush(ctxt, input) < 0)
+ goto error;
+
+ xmlFree(uri);
+ return(ctxt);
+
+error:
+ xmlFree(uri);
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
}
/************************************************************************
@@ -13684,6 +12658,8 @@ xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
* @filename: the filename or URL
* @options: a combination of xmlParserOption
*
+ * DEPRECATED: Use xmlNewParserCtxt and xmlCtxtReadFile.
+ *
* Create a parser context for a file or URL content.
* Automatic support for ZLIB/Compress compressed document is provided
* by default if found at compile-time and for file accesses
@@ -13694,30 +12670,21 @@ xmlParserCtxtPtr
xmlCreateURLParserCtxt(const char *filename, int options)
{
xmlParserCtxtPtr ctxt;
- xmlParserInputPtr inputStream;
- char *directory = NULL;
+ xmlParserInputPtr input;
ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- xmlErrMemory(NULL, "cannot allocate parser context");
+ if (ctxt == NULL)
return(NULL);
- }
- if (options)
- xmlCtxtUseOptionsInternal(ctxt, options);
+ xmlCtxtUseOptions(ctxt, options);
ctxt->linenumbers = 1;
- inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
- if (inputStream == NULL) {
+ input = xmlLoadExternalEntity(filename, NULL, ctxt);
+ if (input == NULL) {
xmlFreeParserCtxt(ctxt);
return(NULL);
}
-
- inputPush(ctxt, inputStream);
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory(filename);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
+ inputPush(ctxt, input);
return(ctxt);
}
@@ -13726,6 +12693,8 @@ xmlCreateURLParserCtxt(const char *filename, int options)
* xmlCreateFileParserCtxt:
* @filename: the filename
*
+ * DEPRECATED: Use xmlNewParserCtxt and xmlCtxtReadFile.
+ *
* Create a parser context for a file content.
* Automatic support for ZLIB/Compress compressed document is provided
* by default if found at compile-time.
@@ -13765,48 +12734,25 @@ xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
int recovery, void *data) {
xmlDocPtr ret;
xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
- xmlInitParser();
-
- ctxt = xmlCreateFileParserCtxt(filename);
- if (ctxt == NULL) {
+ ctxt = xmlNewSAXParserCtxt(sax, NULL);
+ if (ctxt == NULL)
return(NULL);
- }
- if (sax != NULL) {
- if (ctxt->sax != NULL)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- }
- xmlDetectSAX2(ctxt);
- if (data!=NULL) {
+
+ if (data != NULL)
ctxt->_private = data;
- }
- if (ctxt->directory == NULL)
- ctxt->directory = xmlParserGetDirectory(filename);
+ if (recovery) {
+ ctxt->options |= XML_PARSE_RECOVER;
+ ctxt->recovery = 1;
+ }
- ctxt->recovery = recovery;
+ input = xmlNewInputURL(ctxt, filename, NULL, NULL, 0);
- xmlParseDocument(ctxt);
+ ret = xmlCtxtParseDocument(ctxt, input);
- if ((ctxt->wellFormed) || recovery) {
- ret = ctxt->myDoc;
- if ((ret != NULL) && (ctxt->input->buf != NULL)) {
- if (ctxt->input->buf->compressed > 0)
- ret->compression = 9;
- else
- ret->compression = ctxt->input->buf->compressed;
- }
- }
- else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- if (sax != NULL)
- ctxt->sax = NULL;
xmlFreeParserCtxt(ctxt);
-
return(ret);
}
@@ -13910,19 +12856,11 @@ xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
if ((ctxt == NULL) || (buffer == NULL))
return;
- input = xmlNewInputStream(ctxt);
- if (input == NULL) {
- xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
- xmlClearParserCtxt(ctxt);
- return;
- }
-
xmlClearParserCtxt(ctxt);
- if (filename != NULL)
- input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
- input->base = buffer;
- input->cur = buffer;
- input->end = &buffer[xmlStrlen(buffer)];
+
+ input = xmlNewInputString(ctxt, filename, (const char *) buffer, NULL, 0);
+ if (input == NULL)
+ return;
inputPush(ctxt, input);
}
@@ -13947,13 +12885,15 @@ xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
ctxt = xmlCreateFileParserCtxt(filename);
if (ctxt == NULL) return -1;
- if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- xmlDetectSAX2(ctxt);
-
- if (user_data != NULL)
+ if (sax != NULL) {
+ if (sax->initialized == XML_SAX2_MAGIC) {
+ *ctxt->sax = *sax;
+ } else {
+ memset(ctxt->sax, 0, sizeof(*ctxt->sax));
+ memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
+ }
ctxt->userData = user_data;
+ }
xmlParseDocument(ctxt);
@@ -13965,8 +12905,6 @@ xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
else
ret = -1;
}
- if (sax != NULL)
- ctxt->sax = NULL;
if (ctxt->myDoc != NULL) {
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
@@ -13988,7 +12926,8 @@ xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
* @buffer: a pointer to a char array
* @size: the size of the array
*
- * Create a parser context for an XML in-memory document.
+ * Create a parser context for an XML in-memory document. The input buffer
+ * must not contain a terminating null byte.
*
* Returns the new parser context or NULL
*/
@@ -13996,35 +12935,21 @@ xmlParserCtxtPtr
xmlCreateMemoryParserCtxt(const char *buffer, int size) {
xmlParserCtxtPtr ctxt;
xmlParserInputPtr input;
- xmlParserInputBufferPtr buf;
- if (buffer == NULL)
- return(NULL);
- if (size <= 0)
+ if (size < 0)
return(NULL);
ctxt = xmlNewParserCtxt();
if (ctxt == NULL)
return(NULL);
- buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
- if (buf == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- input = xmlNewInputStream(ctxt);
+ input = xmlNewInputMemory(ctxt, NULL, buffer, size, NULL, 0);
if (input == NULL) {
- xmlFreeParserInputBuffer(buf);
xmlFreeParserCtxt(ctxt);
return(NULL);
}
-
- input->filename = NULL;
- input->buf = buf;
- xmlBufResetInput(input->buf->buffer, input);
-
inputPush(ctxt, input);
+
return(ctxt);
}
@@ -14052,38 +12977,32 @@ xmlCreateMemoryParserCtxt(const char *buffer, int size) {
xmlDocPtr
xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
- int size, int recovery, void *data) {
+ int size, int recovery, void *data) {
xmlDocPtr ret;
xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
- xmlInitParser();
+ if (size < 0)
+ return(NULL);
- ctxt = xmlCreateMemoryParserCtxt(buffer, size);
- if (ctxt == NULL) return(NULL);
- if (sax != NULL) {
- if (ctxt->sax != NULL)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- }
- xmlDetectSAX2(ctxt);
- if (data!=NULL) {
+ ctxt = xmlNewSAXParserCtxt(sax, NULL);
+ if (ctxt == NULL)
+ return(NULL);
+
+ if (data != NULL)
ctxt->_private=data;
+
+ if (recovery) {
+ ctxt->options |= XML_PARSE_RECOVER;
+ ctxt->recovery = 1;
}
- ctxt->recovery = recovery;
+ input = xmlNewInputMemory(ctxt, NULL, buffer, size, NULL,
+ XML_INPUT_BUF_STATIC);
- xmlParseDocument(ctxt);
+ ret = xmlCtxtParseDocument(ctxt, input);
- if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
- else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- if (sax != NULL)
- ctxt->sax = NULL;
xmlFreeParserCtxt(ctxt);
-
return(ret);
}
@@ -14161,17 +13080,17 @@ int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
int ret = 0;
xmlParserCtxtPtr ctxt;
- xmlInitParser();
-
ctxt = xmlCreateMemoryParserCtxt(buffer, size);
if (ctxt == NULL) return -1;
- if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- xmlDetectSAX2(ctxt);
-
- if (user_data != NULL)
+ if (sax != NULL) {
+ if (sax->initialized == XML_SAX2_MAGIC) {
+ *ctxt->sax = *sax;
+ } else {
+ memset(ctxt->sax, 0, sizeof(*ctxt->sax));
+ memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
+ }
ctxt->userData = user_data;
+ }
xmlParseDocument(ctxt);
@@ -14183,8 +13102,6 @@ int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
else
ret = -1;
}
- if (sax != NULL)
- ctxt->sax = NULL;
if (ctxt->myDoc != NULL) {
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
@@ -14207,33 +13124,18 @@ xmlParserCtxtPtr
xmlCreateDocParserCtxt(const xmlChar *str) {
xmlParserCtxtPtr ctxt;
xmlParserInputPtr input;
- xmlParserInputBufferPtr buf;
-
- if (str == NULL)
- return(NULL);
ctxt = xmlNewParserCtxt();
if (ctxt == NULL)
return(NULL);
- buf = xmlParserInputBufferCreateString(str);
- if (buf == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- input = xmlNewInputStream(ctxt);
+ input = xmlNewInputString(ctxt, NULL, (const char *) str, NULL, 0);
if (input == NULL) {
- xmlFreeParserInputBuffer(buf);
xmlFreeParserCtxt(ctxt);
return(NULL);
}
-
- input->filename = NULL;
- input->buf = buf;
- xmlBufResetInput(input->buf->buffer, input);
-
inputPush(ctxt, input);
+
return(ctxt);
}
@@ -14270,7 +13172,6 @@ xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
ctxt->sax = sax;
ctxt->userData = NULL;
}
- xmlDetectSAX2(ctxt);
xmlParseDocument(ctxt);
if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
@@ -14303,47 +13204,6 @@ xmlParseDoc(const xmlChar *cur) {
}
#endif /* LIBXML_SAX1_ENABLED */
-#ifdef LIBXML_LEGACY_ENABLED
-/************************************************************************
- * *
- * Specific function to keep track of entities references *
- * and used by the XSLT debugger *
- * *
- ************************************************************************/
-
-static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
-
-/**
- * xmlAddEntityReference:
- * @ent : A valid entity
- * @firstNode : A valid first node for children of entity
- * @lastNode : A valid last node of children entity
- *
- * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
- */
-static void
-xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
- xmlNodePtr lastNode)
-{
- if (xmlEntityRefFunc != NULL) {
- (*xmlEntityRefFunc) (ent, firstNode, lastNode);
- }
-}
-
-
-/**
- * xmlSetEntityReferenceFunc:
- * @func: A valid function
- *
- * Set the function to call call back when a xml reference has been made
- */
-void
-xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
-{
- xmlEntityRefFunc = func;
-}
-#endif /* LIBXML_LEGACY_ENABLED */
-
/************************************************************************
* *
* New set (2.6.0) of simpler and more flexible APIs *
@@ -14407,8 +13267,6 @@ xmlCtxtReset(xmlParserCtxtPtr ctxt)
ctxt->version = NULL;
DICT_FREE(ctxt->encoding);
ctxt->encoding = NULL;
- DICT_FREE(ctxt->directory);
- ctxt->directory = NULL;
DICT_FREE(ctxt->extSubURI);
ctxt->extSubURI = NULL;
DICT_FREE(ctxt->extSubSystem);
@@ -14421,9 +13279,7 @@ xmlCtxtReset(xmlParserCtxtPtr ctxt)
ctxt->hasExternalSubset = 0;
ctxt->hasPErefs = 0;
ctxt->html = 0;
- ctxt->external = 0;
ctxt->instate = XML_PARSER_START;
- ctxt->token = 0;
ctxt->wellFormed = 1;
ctxt->nsWellFormed = 1;
@@ -14480,208 +13336,258 @@ int
xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
int size, const char *filename, const char *encoding)
{
- xmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
+ xmlParserInputPtr input;
if (ctxt == NULL)
return(1);
- buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
- if (buf == NULL)
- return(1);
-
- if (ctxt == NULL) {
- xmlFreeParserInputBuffer(buf);
- return(1);
- }
-
xmlCtxtReset(ctxt);
- if (filename == NULL) {
- ctxt->directory = NULL;
- } else {
- ctxt->directory = xmlParserGetDirectory(filename);
- }
-
- inputStream = xmlNewInputStream(ctxt);
- if (inputStream == NULL) {
- xmlFreeParserInputBuffer(buf);
+ input = xmlNewInputPush(ctxt, filename, chunk, size, encoding);
+ if (input == NULL)
return(1);
- }
-
- if (filename == NULL)
- inputStream->filename = NULL;
- else
- inputStream->filename = (char *)
- xmlCanonicPath((const xmlChar *) filename);
- inputStream->buf = buf;
- xmlBufResetInput(buf->buffer, inputStream);
+ inputPush(ctxt, input);
- inputPush(ctxt, inputStream);
+ return(0);
+}
- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL)) {
- size_t pos = ctxt->input->cur - ctxt->input->base;
- int res;
+static int
+xmlCtxtSetOptionsInternal(xmlParserCtxtPtr ctxt, int options, int keepMask)
+{
+ int allMask;
- res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
- xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
- if (res < 0) {
- xmlFatalErr(ctxt, ctxt->input->buf->error, NULL);
- xmlHaltParser(ctxt);
- return(1);
- }
- }
+ if (ctxt == NULL)
+ return(-1);
- if (encoding != NULL) {
- xmlCharEncodingHandlerPtr hdlr;
+ /*
+ * XInclude options aren't handled by the parser.
+ *
+ * XML_PARSE_XINCLUDE
+ * XML_PARSE_NOXINCNODE
+ * XML_PARSE_NOBASEFIX
+ */
+ allMask = XML_PARSE_RECOVER |
+ XML_PARSE_NOENT |
+ XML_PARSE_DTDLOAD |
+ XML_PARSE_DTDATTR |
+ XML_PARSE_DTDVALID |
+ XML_PARSE_NOERROR |
+ XML_PARSE_NOWARNING |
+ XML_PARSE_PEDANTIC |
+ XML_PARSE_NOBLANKS |
+#ifdef LIBXML_SAX1_ENABLED
+ XML_PARSE_SAX1 |
+#endif
+ XML_PARSE_NONET |
+ XML_PARSE_NODICT |
+ XML_PARSE_NSCLEAN |
+ XML_PARSE_NOCDATA |
+ XML_PARSE_COMPACT |
+ XML_PARSE_OLD10 |
+ XML_PARSE_HUGE |
+ XML_PARSE_OLDSAX |
+ XML_PARSE_IGNORE_ENC |
+ XML_PARSE_BIG_LINES |
+ XML_PARSE_NO_XXE;
+
+ ctxt->options = (ctxt->options & keepMask) | (options & allMask);
+
+ /*
+ * For some options, struct members are historically the source
+ * of truth. The values are initalized from global variables and
+ * old code could also modify them directly. Several older API
+ * functions that don't take an options argument rely on these
+ * deprecated mechanisms.
+ *
+ * Once public access to struct members and the globals are
+ * disabled, we can use the options bitmask as source of
+ * truth, making all these struct members obsolete.
+ *
+ * The XML_DETECT_IDS flags is misnamed. It simply enables
+ * loading of the external subset.
+ */
+ ctxt->recovery = (options & XML_PARSE_RECOVER) ? 1 : 0;
+ ctxt->replaceEntities = (options & XML_PARSE_NOENT) ? 1 : 0;
+ ctxt->loadsubset = (options & XML_PARSE_DTDLOAD) ? XML_DETECT_IDS : 0;
+ ctxt->loadsubset |= (options & XML_PARSE_DTDATTR) ? XML_COMPLETE_ATTRS : 0;
+ ctxt->validate = (options & XML_PARSE_DTDVALID) ? 1 : 0;
+ ctxt->pedantic = (options & XML_PARSE_PEDANTIC) ? 1 : 0;
+ ctxt->keepBlanks = (options & XML_PARSE_NOBLANKS) ? 0 : 1;
+ ctxt->dictNames = (options & XML_PARSE_NODICT) ? 0 : 1;
- hdlr = xmlFindCharEncodingHandler(encoding);
- if (hdlr != NULL) {
- xmlSwitchToEncoding(ctxt, hdlr);
- } else {
- xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
- "Unsupported encoding %s\n", BAD_CAST encoding);
- }
+ /*
+ * Changing SAX callbacks is a bad idea. This should be fixed.
+ */
+ if (options & XML_PARSE_NOBLANKS) {
+ ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+ }
+ if (options & XML_PARSE_NOCDATA) {
+ ctxt->sax->cdataBlock = NULL;
+ }
+ if (options & XML_PARSE_HUGE) {
+ if (ctxt->dict != NULL)
+ xmlDictSetLimit(ctxt->dict, 0);
}
- return(0);
-}
+ ctxt->linenumbers = 1;
+ return(options & ~allMask);
+}
/**
- * xmlCtxtUseOptionsInternal:
+ * xmlCtxtSetOptions:
* @ctxt: an XML parser context
- * @options: a combination of xmlParserOption
- * @encoding: the user provided encoding to use
+ * @options: a bitmask of xmlParserOption values
+ *
+ * Applies the options to the parser context. Unset options are
+ * cleared.
+ *
+ * Available since 2.13.0. With older versions, you can use
+ * xmlCtxtUseOptions.
+ *
+ * XML_PARSE_RECOVER
+ *
+ * Enable "recovery" mode which allows non-wellformed documents.
+ * How this mode behaves exactly is unspecified and may change
+ * without further notice. Use of this feature is DISCOURAGED.
+ *
+ * XML_PARSE_NOENT
+ *
+ * Despite the confusing name, this option enables substitution
+ * of entities. The resulting tree won't contain any entity
+ * reference nodes.
+ *
+ * This option also enables loading of external entities (both
+ * general and parameter entities) which is dangerous. If you
+ * process untrusted data, it's recommended to set the
+ * XML_PARSE_NO_XXE option to disable loading of external
+ * entities.
+ *
+ * XML_PARSE_DTDLOAD
+ *
+ * Enables loading of an external DTD and the loading and
+ * substitution of external parameter entities. Has no effect
+ * if XML_PARSE_NO_XXE is set.
+ *
+ * XML_PARSE_DTDATTR
+ *
+ * Adds default attributes from the DTD to the result document.
+ *
+ * Implies XML_PARSE_DTDLOAD, but loading of external content
+ * can be disabled with XML_PARSE_NO_XXE.
+ *
+ * XML_PARSE_DTDVALID
+ *
+ * This option enables DTD validation which requires to load
+ * external DTDs and external entities (both general and
+ * parameter entities) unless XML_PARSE_NO_XXE was set.
+ *
+ * XML_PARSE_NO_XXE
+ *
+ * Disables loading of external DTDs or entities.
+ *
+ * XML_PARSE_NOERROR
+ *
+ * Disable error and warning reports to the error handlers.
+ * Errors are still accessible with xmlCtxtGetLastError.
+ *
+ * XML_PARSE_NOWARNING
+ *
+ * Disable warning reports.
+ *
+ * XML_PARSE_PEDANTIC
+ *
+ * Enable some pedantic warnings.
+ *
+ * XML_PARSE_NOBLANKS
+ *
+ * Remove some text nodes containing only whitespace from the
+ * result document. Which nodes are removed depends on DTD
+ * element declarations or a conservative heuristic. The
+ * reindenting feature of the serialization code relies on this
+ * option to be set when parsing. Use of this option is
+ * DISCOURAGED.
+ *
+ * XML_PARSE_SAX1
+ *
+ * Always invoke the deprecated SAX1 startElement and endElement
+ * handlers. This option is DEPRECATED.
+ *
+ * XML_PARSE_NONET
+ *
+ * Disable network access with the builtin HTTP and FTP clients.
+ *
+ * XML_PARSE_NODICT
+ *
+ * Create a document without interned strings, making all
+ * strings separate memory allocations.
+ *
+ * XML_PARSE_NSCLEAN
+ *
+ * Remove redundant namespace declarations from the result
+ * document.
+ *
+ * XML_PARSE_NOCDATA
+ *
+ * Output normal text nodes instead of CDATA nodes.
+ *
+ * XML_PARSE_COMPACT
*
- * Applies the options to the parser context
+ * Store small strings directly in the node struct to save
+ * memory.
+ *
+ * XML_PARSE_OLD10
+ *
+ * Use old Name productions from before XML 1.0 Fifth Edition.
+ * This options is DEPRECATED.
+ *
+ * XML_PARSE_HUGE
+ *
+ * Relax some internal limits.
+ *
+ * Maximum size of text nodes, tags, comments, processing instructions,
+ * CDATA sections, entity values
+ *
+ * normal: 10M
+ * huge: 1B
+ *
+ * Maximum size of names, system literals, pubid literals
+ *
+ * normal: 50K
+ * huge: 10M
+ *
+ * Maximum nesting depth of elements
+ *
+ * normal: 256
+ * huge: 2048
+ *
+ * Maximum nesting depth of entities
+ *
+ * normal: 20
+ * huge: 40
+ *
+ * XML_PARSE_OLDSAX
+ *
+ * Enable an unspecified legacy mode for SAX parsers. This
+ * option is DEPRECATED.
+ *
+ * XML_PARSE_IGNORE_ENC
+ *
+ * Ignore the encoding in the XML declaration. This option is
+ * mostly unneeded these days. The only effect is to enforce
+ * UTF-8 decoding of ASCII-like data.
+ *
+ * XML_PARSE_BIG_LINES
+ *
+ * Enable reporting of line numbers larger than 65535.
*
* Returns 0 in case of success, the set of unknown or unimplemented options
* in case of error.
*/
-static int
-xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options)
+int
+xmlCtxtSetOptions(xmlParserCtxtPtr ctxt, int options)
{
- if (ctxt == NULL)
- return(-1);
- if (options & XML_PARSE_RECOVER) {
- ctxt->recovery = 1;
- options -= XML_PARSE_RECOVER;
- ctxt->options |= XML_PARSE_RECOVER;
- } else
- ctxt->recovery = 0;
- if (options & XML_PARSE_DTDLOAD) {
- ctxt->loadsubset = XML_DETECT_IDS;
- options -= XML_PARSE_DTDLOAD;
- ctxt->options |= XML_PARSE_DTDLOAD;
- } else
- ctxt->loadsubset = 0;
- if (options & XML_PARSE_DTDATTR) {
- ctxt->loadsubset |= XML_COMPLETE_ATTRS;
- options -= XML_PARSE_DTDATTR;
- ctxt->options |= XML_PARSE_DTDATTR;
- }
- if (options & XML_PARSE_NOENT) {
- ctxt->replaceEntities = 1;
- /* ctxt->loadsubset |= XML_DETECT_IDS; */
- options -= XML_PARSE_NOENT;
- ctxt->options |= XML_PARSE_NOENT;
- } else
- ctxt->replaceEntities = 0;
- if (options & XML_PARSE_PEDANTIC) {
- ctxt->pedantic = 1;
- options -= XML_PARSE_PEDANTIC;
- ctxt->options |= XML_PARSE_PEDANTIC;
- } else
- ctxt->pedantic = 0;
- if (options & XML_PARSE_NOBLANKS) {
- ctxt->keepBlanks = 0;
- ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
- options -= XML_PARSE_NOBLANKS;
- ctxt->options |= XML_PARSE_NOBLANKS;
- } else
- ctxt->keepBlanks = 1;
- if (options & XML_PARSE_DTDVALID) {
- ctxt->validate = 1;
- if (options & XML_PARSE_NOWARNING)
- ctxt->vctxt.warning = NULL;
- if (options & XML_PARSE_NOERROR)
- ctxt->vctxt.error = NULL;
- options -= XML_PARSE_DTDVALID;
- ctxt->options |= XML_PARSE_DTDVALID;
- } else
- ctxt->validate = 0;
- if (options & XML_PARSE_NOWARNING) {
- ctxt->sax->warning = NULL;
- options -= XML_PARSE_NOWARNING;
- }
- if (options & XML_PARSE_NOERROR) {
- ctxt->sax->error = NULL;
- ctxt->sax->fatalError = NULL;
- options -= XML_PARSE_NOERROR;
- }
-#ifdef LIBXML_SAX1_ENABLED
- if (options & XML_PARSE_SAX1) {
- ctxt->sax->startElementNs = NULL;
- ctxt->sax->endElementNs = NULL;
- ctxt->sax->initialized = 1;
- options -= XML_PARSE_SAX1;
- ctxt->options |= XML_PARSE_SAX1;
- }
-#endif /* LIBXML_SAX1_ENABLED */
- if (options & XML_PARSE_NODICT) {
- ctxt->dictNames = 0;
- options -= XML_PARSE_NODICT;
- ctxt->options |= XML_PARSE_NODICT;
- } else {
- ctxt->dictNames = 1;
- }
- if (options & XML_PARSE_NOCDATA) {
- ctxt->sax->cdataBlock = NULL;
- options -= XML_PARSE_NOCDATA;
- ctxt->options |= XML_PARSE_NOCDATA;
- }
- if (options & XML_PARSE_NSCLEAN) {
- ctxt->options |= XML_PARSE_NSCLEAN;
- options -= XML_PARSE_NSCLEAN;
- }
- if (options & XML_PARSE_NONET) {
- ctxt->options |= XML_PARSE_NONET;
- options -= XML_PARSE_NONET;
- }
- if (options & XML_PARSE_COMPACT) {
- ctxt->options |= XML_PARSE_COMPACT;
- options -= XML_PARSE_COMPACT;
- }
- if (options & XML_PARSE_OLD10) {
- ctxt->options |= XML_PARSE_OLD10;
- options -= XML_PARSE_OLD10;
- }
- if (options & XML_PARSE_NOBASEFIX) {
- ctxt->options |= XML_PARSE_NOBASEFIX;
- options -= XML_PARSE_NOBASEFIX;
- }
- if (options & XML_PARSE_HUGE) {
- ctxt->options |= XML_PARSE_HUGE;
- options -= XML_PARSE_HUGE;
- if (ctxt->dict != NULL)
- xmlDictSetLimit(ctxt->dict, 0);
- }
- if (options & XML_PARSE_OLDSAX) {
- ctxt->options |= XML_PARSE_OLDSAX;
- options -= XML_PARSE_OLDSAX;
- }
- if (options & XML_PARSE_IGNORE_ENC) {
- ctxt->options |= XML_PARSE_IGNORE_ENC;
- options -= XML_PARSE_IGNORE_ENC;
- }
- if (options & XML_PARSE_BIG_LINES) {
- ctxt->options |= XML_PARSE_BIG_LINES;
- options -= XML_PARSE_BIG_LINES;
- }
- ctxt->linenumbers = 1;
- return (options);
+ return(xmlCtxtSetOptionsInternal(ctxt, options, 0));
}
/**
@@ -14689,7 +13595,22 @@ xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options)
* @ctxt: an XML parser context
* @options: a combination of xmlParserOption
*
- * Applies the options to the parser context
+ * DEPRECATED: Use xmlCtxtSetOptions.
+ *
+ * Applies the options to the parser context. The following options
+ * are never cleared and can only be enabled:
+ *
+ * XML_PARSE_NOERROR
+ * XML_PARSE_NOWARNING
+ * XML_PARSE_NONET
+ * XML_PARSE_NSCLEAN
+ * XML_PARSE_NOCDATA
+ * XML_PARSE_COMPACT
+ * XML_PARSE_OLD10
+ * XML_PARSE_HUGE
+ * XML_PARSE_OLDSAX
+ * XML_PARSE_IGNORE_ENC
+ * XML_PARSE_BIG_LINES
*
* Returns 0 in case of success, the set of unknown or unimplemented options
* in case of error.
@@ -14697,7 +13618,24 @@ xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options)
int
xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
{
- return(xmlCtxtUseOptionsInternal(ctxt, options));
+ int keepMask;
+
+ /*
+ * For historic reasons, some options can only be enabled.
+ */
+ keepMask = XML_PARSE_NOERROR |
+ XML_PARSE_NOWARNING |
+ XML_PARSE_NONET |
+ XML_PARSE_NSCLEAN |
+ XML_PARSE_NOCDATA |
+ XML_PARSE_COMPACT |
+ XML_PARSE_OLD10 |
+ XML_PARSE_HUGE |
+ XML_PARSE_OLDSAX |
+ XML_PARSE_IGNORE_ENC |
+ XML_PARSE_BIG_LINES;
+
+ return(xmlCtxtSetOptionsInternal(ctxt, options, keepMask));
}
/**
@@ -14720,90 +13658,102 @@ xmlCtxtSetMaxAmplification(xmlParserCtxtPtr ctxt, unsigned maxAmpl)
}
/**
- * xmlDoRead:
+ * xmlCtxtParseDocument:
* @ctxt: an XML parser context
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
- * @options: a combination of xmlParserOption
- * @reuse: keep the context for reuse
+ * @input: parser input
*
- * Common front-end for the xmlRead functions
+ * Parse an XML document and return the resulting document tree.
+ * Takes ownership of the input object.
+ *
+ * Available since 2.13.0.
*
* Returns the resulting document tree or NULL
*/
-static xmlDocPtr
-xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
- int options, int reuse)
+xmlDocPtr
+xmlCtxtParseDocument(xmlParserCtxtPtr ctxt, xmlParserInputPtr input)
{
- xmlDocPtr ret;
+ xmlDocPtr ret = NULL;
- xmlCtxtUseOptionsInternal(ctxt, options);
- if (encoding != NULL) {
- xmlCharEncodingHandlerPtr hdlr;
+ if ((ctxt == NULL) || (input == NULL))
+ return(NULL);
- /*
- * TODO: We should consider to set XML_PARSE_IGNORE_ENC if the
- * caller provided an encoding. Otherwise, we might switch to
- * the encoding from the XML declaration which is likely to
- * break things. Also see xmlSwitchInputEncoding.
- */
- hdlr = xmlFindCharEncodingHandler(encoding);
- if (hdlr != NULL)
- xmlSwitchToEncoding(ctxt, hdlr);
+ /* assert(ctxt->inputNr == 0); */
+ while (ctxt->inputNr > 0)
+ xmlFreeInputStream(inputPop(ctxt));
+
+ if (inputPush(ctxt, input) < 0) {
+ xmlFreeInputStream(input);
+ return(NULL);
}
- if ((URL != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->filename == NULL))
- ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
+
xmlParseDocument(ctxt);
- if ((ctxt->wellFormed) || ctxt->recovery)
+
+ if ((ctxt->wellFormed) ||
+ ((ctxt->recovery) && (ctxt->errNo != XML_ERR_NO_MEMORY))) {
ret = ctxt->myDoc;
- else {
+ } else {
+ if (ctxt->errNo == XML_ERR_OK)
+ xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, "unknown error\n");
+
ret = NULL;
- if (ctxt->myDoc != NULL) {
- xmlFreeDoc(ctxt->myDoc);
- }
+ xmlFreeDoc(ctxt->myDoc);
}
ctxt->myDoc = NULL;
- if (!reuse) {
- xmlFreeParserCtxt(ctxt);
- }
- return (ret);
+ /* assert(ctxt->inputNr == 1); */
+ while (ctxt->inputNr > 0)
+ xmlFreeInputStream(inputPop(ctxt));
+
+ return(ret);
}
/**
* xmlReadDoc:
* @cur: a pointer to a zero terminated string
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
+ * @URL: base URL (optional)
+ * @encoding: the document encoding (optional)
* @options: a combination of xmlParserOption
*
- * parse an XML in-memory document and build a tree.
+ * Convenience function to parse an XML document from a
+ * zero-terminated string.
+ *
+ * See xmlCtxtReadDoc for details.
*
* Returns the resulting document tree
*/
xmlDocPtr
-xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
+xmlReadDoc(const xmlChar *cur, const char *URL, const char *encoding,
+ int options)
{
xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
+ xmlDocPtr doc;
- if (cur == NULL)
- return (NULL);
- xmlInitParser();
-
- ctxt = xmlCreateDocParserCtxt(cur);
+ ctxt = xmlNewParserCtxt();
if (ctxt == NULL)
- return (NULL);
- return (xmlDoRead(ctxt, URL, encoding, options, 0));
+ return(NULL);
+
+ xmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputString(ctxt, URL, (const char *) cur, encoding,
+ XML_INPUT_BUF_STATIC);
+
+ doc = xmlCtxtParseDocument(ctxt, input);
+
+ xmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* xmlReadFile:
* @filename: a file or URL
- * @encoding: the document encoding, or NULL
+ * @encoding: the document encoding (optional)
* @options: a combination of xmlParserOption
*
- * parse an XML file from the filesystem or the network.
+ * Convenience function to parse an XML file from the filesystem,
+ * the network or a global user-define resource loader.
+ *
+ * See xmlCtxtReadFile for details.
*
* Returns the resulting document tree
*/
@@ -14811,48 +13761,77 @@ xmlDocPtr
xmlReadFile(const char *filename, const char *encoding, int options)
{
xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
+ xmlDocPtr doc;
- xmlInitParser();
- ctxt = xmlCreateURLParserCtxt(filename, options);
+ ctxt = xmlNewParserCtxt();
if (ctxt == NULL)
- return (NULL);
- return (xmlDoRead(ctxt, NULL, encoding, options, 0));
+ return(NULL);
+
+ xmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
+
+ doc = xmlCtxtParseDocument(ctxt, input);
+
+ xmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* xmlReadMemory:
* @buffer: a pointer to a char array
* @size: the size of the array
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
+ * @url: base URL (optional)
+ * @encoding: the document encoding (optional)
* @options: a combination of xmlParserOption
*
- * parse an XML in-memory document and build a tree.
+ * Parse an XML in-memory document and build a tree. The input buffer must
+ * not contain a terminating null byte.
+ *
+ * See xmlCtxtReadMemory for details.
*
* Returns the resulting document tree
*/
xmlDocPtr
-xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
+xmlReadMemory(const char *buffer, int size, const char *url,
+ const char *encoding, int options)
{
xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
+ xmlDocPtr doc;
- xmlInitParser();
- ctxt = xmlCreateMemoryParserCtxt(buffer, size);
+ if (size < 0)
+ return(NULL);
+
+ ctxt = xmlNewParserCtxt();
if (ctxt == NULL)
- return (NULL);
- return (xmlDoRead(ctxt, URL, encoding, options, 0));
+ return(NULL);
+
+ xmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputMemory(ctxt, url, buffer, size, encoding,
+ XML_INPUT_BUF_STATIC);
+
+ doc = xmlCtxtParseDocument(ctxt, input);
+
+ xmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* xmlReadFd:
* @fd: an open file descriptor
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
+ * @URL: base URL (optional)
+ * @encoding: the document encoding (optional)
* @options: a combination of xmlParserOption
*
- * parse an XML from a file descriptor and build a tree.
+ * Parse an XML from a file descriptor and build a tree.
+ *
+ * See xmlCtxtReadFd for details.
+ *
* NOTE that the file descriptor will not be closed when the
- * reader is closed or reset.
+ * context is freed or reset.
*
* Returns the resulting document tree
*/
@@ -14860,42 +13839,35 @@ xmlDocPtr
xmlReadFd(int fd, const char *URL, const char *encoding, int options)
{
xmlParserCtxtPtr ctxt;
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
-
- if (fd < 0)
- return (NULL);
- xmlInitParser();
+ xmlParserInputPtr input;
+ xmlDocPtr doc;
- input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
- if (input == NULL)
- return (NULL);
- input->closecallback = NULL;
ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- xmlFreeParserInputBuffer(input);
- return (NULL);
- }
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- xmlFreeParserCtxt(ctxt);
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (xmlDoRead(ctxt, URL, encoding, options, 0));
+ if (ctxt == NULL)
+ return(NULL);
+
+ xmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputFd(ctxt, URL, fd, encoding, 0);
+
+ doc = xmlCtxtParseDocument(ctxt, input);
+
+ xmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* xmlReadIO:
* @ioread: an I/O read function
- * @ioclose: an I/O close function
+ * @ioclose: an I/O close function (optional)
* @ioctx: an I/O handler
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
+ * @URL: base URL (optional)
+ * @encoding: the document encoding (optional)
* @options: a combination of xmlParserOption
*
- * parse an XML document from I/O functions and source and build a tree.
+ * Parse an XML document from I/O functions and context and build a tree.
+ *
+ * See xmlCtxtReadIO for details.
*
* Returns the resulting document tree
*/
@@ -14904,45 +13876,37 @@ xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
void *ioctx, const char *URL, const char *encoding, int options)
{
xmlParserCtxtPtr ctxt;
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
-
- if (ioread == NULL)
- return (NULL);
- xmlInitParser();
+ xmlParserInputPtr input;
+ xmlDocPtr doc;
- input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
- XML_CHAR_ENCODING_NONE);
- if (input == NULL) {
- if (ioclose != NULL)
- ioclose(ioctx);
- return (NULL);
- }
ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- xmlFreeParserInputBuffer(input);
- return (NULL);
- }
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- xmlFreeParserCtxt(ctxt);
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (xmlDoRead(ctxt, URL, encoding, options, 0));
+ if (ctxt == NULL)
+ return(NULL);
+
+ xmlCtxtUseOptions(ctxt, options);
+
+ input = xmlNewInputIO(ctxt, URL, ioread, ioclose, ioctx, encoding, 0);
+
+ doc = xmlCtxtParseDocument(ctxt, input);
+
+ xmlFreeParserCtxt(ctxt);
+ return(doc);
}
/**
* xmlCtxtReadDoc:
* @ctxt: an XML parser context
* @str: a pointer to a zero terminated string
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
+ * @URL: base URL (optional)
+ * @encoding: the document encoding (optional)
* @options: a combination of xmlParserOption
*
- * parse an XML in-memory document and build a tree.
- * This reuses the existing @ctxt parser context
+ * Parse an XML in-memory document and build a tree.
+ *
+ * @URL is used as base to resolve external entities and for error
+ * reporting.
+ *
+ * See xmlCtxtUseOptions for details.
*
* Returns the resulting document tree
*/
@@ -14950,41 +13914,31 @@ xmlDocPtr
xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar *str,
const char *URL, const char *encoding, int options)
{
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
if (ctxt == NULL)
- return (NULL);
- if (str == NULL)
- return (NULL);
- xmlInitParser();
+ return(NULL);
xmlCtxtReset(ctxt);
+ xmlCtxtUseOptions(ctxt, options);
- input = xmlParserInputBufferCreateString(str);
- if (input == NULL) {
- return(NULL);
- }
-
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- return(NULL);
- }
+ input = xmlNewInputString(ctxt, URL, (const char *) str, encoding,
+ XML_INPUT_BUF_STATIC);
- inputPush(ctxt, stream);
- return (xmlDoRead(ctxt, URL, encoding, options, 1));
+ return(xmlCtxtParseDocument(ctxt, input));
}
/**
* xmlCtxtReadFile:
* @ctxt: an XML parser context
* @filename: a file or URL
- * @encoding: the document encoding, or NULL
+ * @encoding: the document encoding (optional)
* @options: a combination of xmlParserOption
*
- * parse an XML file from the filesystem or the network.
- * This reuses the existing @ctxt parser context
+ * Parse an XML file from the filesystem, the network or a user-defined
+ * resource loader.
+ *
+ * See xmlNewInputURL and xmlCtxtUseOptions for details.
*
* Returns the resulting document tree
*/
@@ -14992,22 +13946,17 @@ xmlDocPtr
xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
const char *encoding, int options)
{
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
- if (filename == NULL)
- return (NULL);
if (ctxt == NULL)
- return (NULL);
- xmlInitParser();
+ return(NULL);
xmlCtxtReset(ctxt);
+ xmlCtxtUseOptions(ctxt, options);
- stream = xmlLoadExternalEntity(filename, NULL, ctxt);
- if (stream == NULL) {
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (xmlDoRead(ctxt, NULL, encoding, options, 1));
+ input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
+
+ return(xmlCtxtParseDocument(ctxt, input));
}
/**
@@ -15015,12 +13964,17 @@ xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
* @ctxt: an XML parser context
* @buffer: a pointer to a char array
* @size: the size of the array
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
+ * @URL: base URL (optional)
+ * @encoding: the document encoding (optional)
* @options: a combination of xmlParserOption
*
- * parse an XML in-memory document and build a tree.
- * This reuses the existing @ctxt parser context
+ * Parse an XML in-memory document and build a tree. The input buffer must
+ * not contain a terminating null byte.
+ *
+ * @URL is used as base to resolve external entities and for error
+ * reporting.
+ *
+ * See xmlCtxtUseOptions for details.
*
* Returns the resulting document tree
*/
@@ -15028,45 +13982,37 @@ xmlDocPtr
xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
const char *URL, const char *encoding, int options)
{
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
- if (ctxt == NULL)
- return (NULL);
- if (buffer == NULL)
- return (NULL);
- xmlInitParser();
+ if ((ctxt == NULL) || (size < 0))
+ return(NULL);
xmlCtxtReset(ctxt);
+ xmlCtxtUseOptions(ctxt, options);
- input = xmlParserInputBufferCreateStatic(buffer, size,
- XML_CHAR_ENCODING_NONE);
- if (input == NULL) {
- return(NULL);
- }
-
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- return(NULL);
- }
+ input = xmlNewInputMemory(ctxt, URL, buffer, size, encoding,
+ XML_INPUT_BUF_STATIC);
- inputPush(ctxt, stream);
- return (xmlDoRead(ctxt, URL, encoding, options, 1));
+ return(xmlCtxtParseDocument(ctxt, input));
}
/**
* xmlCtxtReadFd:
* @ctxt: an XML parser context
* @fd: an open file descriptor
- * @URL: the base URL to use for the document
- * @encoding: the document encoding, or NULL
+ * @URL: base URL (optional)
+ * @encoding: the document encoding (optional)
* @options: a combination of xmlParserOption
*
- * parse an XML from a file descriptor and build a tree.
- * This reuses the existing @ctxt parser context
+ * Parse an XML document from a file descriptor and build a tree.
+ *
* NOTE that the file descriptor will not be closed when the
- * reader is closed or reset.
+ * context is freed or reset.
+ *
+ * @URL is used as base to resolve external entities and for error
+ * reporting.
+ *
+ * See xmlCtxtUseOptions for details.
*
* Returns the resulting document tree
*/
@@ -15074,29 +14020,17 @@ xmlDocPtr
xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
const char *URL, const char *encoding, int options)
{
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
- if (fd < 0)
- return (NULL);
if (ctxt == NULL)
- return (NULL);
- xmlInitParser();
+ return(NULL);
xmlCtxtReset(ctxt);
+ xmlCtxtUseOptions(ctxt, options);
+ input = xmlNewInputFd(ctxt, URL, fd, encoding, 0);
- input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
- if (input == NULL)
- return (NULL);
- input->closecallback = NULL;
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (xmlDoRead(ctxt, URL, encoding, options, 1));
+ return(xmlCtxtParseDocument(ctxt, input));
}
/**
@@ -15112,6 +14046,11 @@ xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
* parse an XML document from I/O functions and source and build a tree.
* This reuses the existing @ctxt parser context
*
+ * @URL is used as base to resolve external entities and for error
+ * reporting.
+ *
+ * See xmlCtxtUseOptions for details.
+ *
* Returns the resulting document tree
*/
xmlDocPtr
@@ -15120,30 +14059,16 @@ xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
const char *URL,
const char *encoding, int options)
{
- xmlParserInputBufferPtr input;
- xmlParserInputPtr stream;
+ xmlParserInputPtr input;
- if (ioread == NULL)
- return (NULL);
if (ctxt == NULL)
- return (NULL);
- xmlInitParser();
+ return(NULL);
xmlCtxtReset(ctxt);
+ xmlCtxtUseOptions(ctxt, options);
- input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
- XML_CHAR_ENCODING_NONE);
- if (input == NULL) {
- if (ioclose != NULL)
- ioclose(ioctx);
- return (NULL);
- }
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
- if (stream == NULL) {
- xmlFreeParserInputBuffer(input);
- return (NULL);
- }
- inputPush(ctxt, stream);
- return (xmlDoRead(ctxt, URL, encoding, options, 1));
+ input = xmlNewInputIO(ctxt, URL, ioread, ioclose, ioctx, encoding, 0);
+
+ return(xmlCtxtParseDocument(ctxt, input));
}
diff --git a/parserInternals.c b/parserInternals.c
index 166397b..6a43cc8 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -35,6 +35,7 @@
#include
#endif
#include
+#include
#define CUR(ctxt) ctxt->input->cur
#define END(ctxt) ctxt->input->end
@@ -45,6 +46,8 @@
#include "private/io.h"
#include "private/parser.h"
+#define XML_MAX_ERRORS 100
+
/*
* XML_MAX_AMPLIFICATION_DEFAULT is the default maximum allowed amplification
* factor of serialized output after entity expansion.
@@ -60,7 +63,6 @@
* @version: the include version number
*
* check the compiled lib version against the include one.
- * This can warn or immediately kill the application
*/
void
xmlCheckVersion(int version) {
@@ -69,15 +71,11 @@ xmlCheckVersion(int version) {
xmlInitParser();
if ((myversion / 10000) != (version / 10000)) {
- xmlGenericError(xmlGenericErrorContext,
- "Fatal: program compiled against libxml %d using libxml %d\n",
- (version / 10000), (myversion / 10000));
fprintf(stderr,
"Fatal: program compiled against libxml %d using libxml %d\n",
(version / 10000), (myversion / 10000));
- }
- if ((myversion / 100) < (version / 100)) {
- xmlGenericError(xmlGenericErrorContext,
+ } else if ((myversion / 100) < (version / 100)) {
+ fprintf(stderr,
"Warning: program compiled against libxml %d using older %d\n",
(version / 100), (myversion / 100));
}
@@ -92,338 +90,293 @@ xmlCheckVersion(int version) {
/**
- * xmlErrMemory:
+ * xmlCtxtSetErrorHandler:
* @ctxt: an XML parser context
- * @extra: extra information
+ * @handler: error handler
+ * @data: data for error handler
+ *
+ * Register a callback function that will be called on errors and
+ * warnings. If handler is NULL, the error handler will be deactivated.
+ *
+ * This is the recommended way to collect errors from the parser and
+ * takes precedence over all other error reporting mechanisms.
+ * These are (in order of precedence):
+ *
+ * - per-context structured handler (xmlCtxtSetErrorHandler)
+ * - per-context structured "serror" SAX handler
+ * - global structured handler (xmlSetStructuredErrorFunc)
+ * - per-context generic "error" and "warning" SAX handlers
+ * - global generic handler (xmlSetGenericErrorFunc)
+ * - print to stderr
*
- * Handle a redefinition of attribute error
+ * Available since 2.13.0.
*/
void
-xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
+xmlCtxtSetErrorHandler(xmlParserCtxtPtr ctxt, xmlStructuredErrorFunc handler,
+ void *data)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL) {
- ctxt->errNo = XML_ERR_NO_MEMORY;
- ctxt->instate = XML_PARSER_EOF;
- ctxt->disableSAX = 1;
- }
- if (extra)
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
- else
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
- NULL, NULL, 0, 0, "Memory allocation failed\n");
+ if (ctxt == NULL)
+ return;
+ ctxt->errorHandler = handler;
+ ctxt->errorCtxt = data;
}
/**
- * __xmlErrEncoding:
+ * xmlCtxtErrMemory:
* @ctxt: an XML parser context
- * @xmlerr: the error number
- * @msg: the error message
- * @str1: an string info
- * @str2: an string info
*
- * Handle an encoding error
+ * Handle an out-of-memory error.
+ *
+ * Available since 2.13.0.
*/
void
-__xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr,
- const char *msg, const xmlChar * str1, const xmlChar * str2)
+xmlCtxtErrMemory(xmlParserCtxtPtr ctxt)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = xmlerr;
- __xmlRaiseError(NULL, NULL, NULL,
- ctxt, NULL, XML_FROM_PARSER, xmlerr, XML_ERR_FATAL,
- NULL, 0, (const char *) str1, (const char *) str2,
- NULL, 0, 0, msg, str1, str2);
- if (ctxt != NULL) {
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0)
- ctxt->disableSAX = 1;
+ xmlStructuredErrorFunc schannel = NULL;
+ xmlGenericErrorFunc channel = NULL;
+ void *data;
+
+ if (ctxt == NULL)
+ return;
+
+ ctxt->errNo = XML_ERR_NO_MEMORY;
+ ctxt->instate = XML_PARSER_EOF; /* TODO: Remove after refactoring */
+ ctxt->wellFormed = 0;
+ ctxt->disableSAX = 2;
+
+ if (ctxt->errorHandler) {
+ schannel = ctxt->errorHandler;
+ data = ctxt->errorCtxt;
+ } else if ((ctxt->sax->initialized == XML_SAX2_MAGIC) &&
+ (ctxt->sax->serror != NULL)) {
+ schannel = ctxt->sax->serror;
+ data = ctxt->userData;
+ } else {
+ channel = ctxt->sax->error;
+ data = ctxt->userData;
}
+
+ xmlRaiseMemoryError(schannel, channel, data, XML_FROM_PARSER,
+ &ctxt->lastError);
}
/**
- * xmlErrInternal:
- * @ctxt: an XML parser context
- * @msg: the error message
- * @str: error information
+ * xmlCtxtErrIO:
+ * @ctxt: parser context
+ * @code: xmlParserErrors code
+ * @uri: filename or URI (optional)
*
- * Handle an internal error
+ * If filename is empty, use the one from context input if available.
+ *
+ * Report an IO error to the parser context.
+ */
+void
+xmlCtxtErrIO(xmlParserCtxtPtr ctxt, int code, const char *uri)
+{
+ const char *errstr, *msg, *str1, *str2;
+ xmlErrorLevel level;
+
+ if (ctxt == NULL)
+ return;
+
+ /*
+ * Don't report a well-formedness error if an external entity could
+ * not be found. We assume that inputNr is zero for the document
+ * entity which is somewhat fragile.
+ */
+ if ((ctxt->inputNr > 0) &&
+ ((code == XML_IO_ENOENT) ||
+ (code == XML_IO_NETWORK_ATTEMPT) ||
+ (code == XML_IO_UNKNOWN))) {
+ if (ctxt->validate == 0)
+ level = XML_ERR_WARNING;
+ else
+ level = XML_ERR_ERROR;
+ } else {
+ level = XML_ERR_FATAL;
+ }
+
+ errstr = xmlErrString(code);
+
+ if (uri == NULL) {
+ msg = "%s\n";
+ str1 = errstr;
+ str2 = NULL;
+ } else {
+ msg = "failed to load \"%s\": %s\n";
+ str1 = uri;
+ str2 = errstr;
+ }
+
+ xmlCtxtErr(ctxt, NULL, XML_FROM_IO, code, level,
+ (const xmlChar *) uri, NULL, NULL, 0,
+ msg, str1, str2);
+}
+
+/**
+ * xmlCtxtVErr:
+ * @ctxt: a parser context
+ * @node: the current node or NULL
+ * @domain: the domain for the error
+ * @code: the code for the error
+ * @level: the xmlErrorLevel for the error
+ * @str1: extra string info
+ * @str2: extra string info
+ * @str3: extra string info
+ * @int1: extra int info
+ * @msg: the message to display/transmit
+ * @ap: extra parameters for the message display
+ *
+ * Raise a parser error.
*/
-static void LIBXML_ATTR_FORMAT(2,0)
-xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
+void
+xmlCtxtVErr(xmlParserCtxtPtr ctxt, xmlNodePtr node, xmlErrorDomain domain,
+ xmlParserErrors code, xmlErrorLevel level,
+ const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
+ int int1, const char *msg, va_list ap)
{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
+ xmlStructuredErrorFunc schannel = NULL;
+ xmlGenericErrorFunc channel = NULL;
+ void *data = NULL;
+ const char *file = NULL;
+ int line = 0;
+ int col = 0;
+ int res;
+
+ if (code == XML_ERR_NO_MEMORY) {
+ xmlCtxtErrMemory(ctxt);
+ return;
+ }
+
+ if (PARSER_STOPPED(ctxt))
return;
- if (ctxt != NULL)
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- __xmlRaiseError(NULL, NULL, NULL,
- ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR,
- XML_ERR_FATAL, NULL, 0, (const char *) str, NULL, NULL,
- 0, 0, msg, str);
- if (ctxt != NULL) {
+
+ if (level == XML_ERR_WARNING) {
+ if (ctxt->nbWarnings >= XML_MAX_ERRORS)
+ return;
+ ctxt->nbWarnings += 1;
+ } else {
+ if (ctxt->nbErrors >= XML_MAX_ERRORS)
+ return;
+ ctxt->nbErrors += 1;
+ }
+
+ if (((ctxt->options & XML_PARSE_NOERROR) == 0) &&
+ ((level != XML_ERR_WARNING) ||
+ ((ctxt->options & XML_PARSE_NOWARNING) == 0))) {
+ if (ctxt->errorHandler) {
+ schannel = ctxt->errorHandler;
+ data = ctxt->errorCtxt;
+ } else if ((ctxt->sax->initialized == XML_SAX2_MAGIC) &&
+ (ctxt->sax->serror != NULL)) {
+ schannel = ctxt->sax->serror;
+ data = ctxt->userData;
+ } else if ((domain == XML_FROM_VALID) || (domain == XML_FROM_DTD)) {
+ if (level == XML_ERR_WARNING)
+ channel = ctxt->vctxt.warning;
+ else
+ channel = ctxt->vctxt.error;
+ data = ctxt->vctxt.userData;
+ } else {
+ if (level == XML_ERR_WARNING)
+ channel = ctxt->sax->warning;
+ else
+ channel = ctxt->sax->error;
+ data = ctxt->userData;
+ }
+ }
+
+ if (ctxt->input != NULL) {
+ xmlParserInputPtr input = ctxt->input;
+
+ if ((input->filename == NULL) &&
+ (ctxt->inputNr > 1)) {
+ input = ctxt->inputTab[ctxt->inputNr - 2];
+ }
+ file = input->filename;
+ line = input->line;
+ col = input->col;
+ }
+
+ res = xmlVRaiseError(schannel, channel, data, ctxt, node, domain, code,
+ level, file, line, (const char *) str1,
+ (const char *) str2, (const char *) str3, int1, col,
+ msg, ap);
+
+ if (res < 0) {
+ xmlCtxtErrMemory(ctxt);
+ return;
+ }
+
+ if (level >= XML_ERR_ERROR)
+ ctxt->errNo = code;
+ if (level == XML_ERR_FATAL) {
ctxt->wellFormed = 0;
if (ctxt->recovery == 0)
ctxt->disableSAX = 1;
}
+
+ return;
+}
+
+/**
+ * xmlCtxtErr:
+ * @ctxt: a parser context
+ * @node: the current node or NULL
+ * @domain: the domain for the error
+ * @code: the code for the error
+ * @level: the xmlErrorLevel for the error
+ * @str1: extra string info
+ * @str2: extra string info
+ * @str3: extra string info
+ * @int1: extra int info
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Raise a parser error.
+ */
+void
+xmlCtxtErr(xmlParserCtxtPtr ctxt, xmlNodePtr node, xmlErrorDomain domain,
+ xmlParserErrors code, xmlErrorLevel level,
+ const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
+ int int1, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ xmlCtxtVErr(ctxt, node, domain, code, level,
+ str1, str2, str3, int1, msg, ap);
+ va_end(ap);
}
/**
* xmlFatalErr:
* @ctxt: an XML parser context
- * @error: the error number
+ * @code: the error number
* @info: extra information string
*
* Handle a fatal parser error, i.e. violating Well-Formedness constraints
*/
void
-xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
+xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors code, const char *info)
{
const char *errmsg;
+ xmlErrorLevel level;
+
+ if (code == XML_ERR_UNSUPPORTED_ENCODING)
+ level = XML_ERR_WARNING;
+ else
+ level = XML_ERR_FATAL;
+
+ errmsg = xmlErrString(code);
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- switch (error) {
- case XML_ERR_INVALID_HEX_CHARREF:
- errmsg = "CharRef: invalid hexadecimal value";
- break;
- case XML_ERR_INVALID_DEC_CHARREF:
- errmsg = "CharRef: invalid decimal value";
- break;
- case XML_ERR_INVALID_CHARREF:
- errmsg = "CharRef: invalid value";
- break;
- case XML_ERR_INTERNAL_ERROR:
- errmsg = "internal error";
- break;
- case XML_ERR_PEREF_AT_EOF:
- errmsg = "PEReference at end of document";
- break;
- case XML_ERR_PEREF_IN_PROLOG:
- errmsg = "PEReference in prolog";
- break;
- case XML_ERR_PEREF_IN_EPILOG:
- errmsg = "PEReference in epilog";
- break;
- case XML_ERR_PEREF_NO_NAME:
- errmsg = "PEReference: no name";
- break;
- case XML_ERR_PEREF_SEMICOL_MISSING:
- errmsg = "PEReference: expecting ';'";
- break;
- case XML_ERR_ENTITY_LOOP:
- errmsg = "Detected an entity reference loop";
- break;
- case XML_ERR_ENTITY_NOT_STARTED:
- errmsg = "EntityValue: \" or ' expected";
- break;
- case XML_ERR_ENTITY_PE_INTERNAL:
- errmsg = "PEReferences forbidden in internal subset";
- break;
- case XML_ERR_ENTITY_NOT_FINISHED:
- errmsg = "EntityValue: \" or ' expected";
- break;
- case XML_ERR_ATTRIBUTE_NOT_STARTED:
- errmsg = "AttValue: \" or ' expected";
- break;
- case XML_ERR_LT_IN_ATTRIBUTE:
- errmsg = "Unescaped '<' not allowed in attributes values";
- break;
- case XML_ERR_LITERAL_NOT_STARTED:
- errmsg = "SystemLiteral \" or ' expected";
- break;
- case XML_ERR_LITERAL_NOT_FINISHED:
- errmsg = "Unfinished System or Public ID \" or ' expected";
- break;
- case XML_ERR_MISPLACED_CDATA_END:
- errmsg = "Sequence ']]>' not allowed in content";
- break;
- case XML_ERR_URI_REQUIRED:
- errmsg = "SYSTEM or PUBLIC, the URI is missing";
- break;
- case XML_ERR_PUBID_REQUIRED:
- errmsg = "PUBLIC, the Public Identifier is missing";
- break;
- case XML_ERR_HYPHEN_IN_COMMENT:
- errmsg = "Comment must not contain '--' (double-hyphen)";
- break;
- case XML_ERR_PI_NOT_STARTED:
- errmsg = "xmlParsePI : no target name";
- break;
- case XML_ERR_RESERVED_XML_NAME:
- errmsg = "Invalid PI name";
- break;
- case XML_ERR_NOTATION_NOT_STARTED:
- errmsg = "NOTATION: Name expected here";
- break;
- case XML_ERR_NOTATION_NOT_FINISHED:
- errmsg = "'>' required to close NOTATION declaration";
- break;
- case XML_ERR_VALUE_REQUIRED:
- errmsg = "Entity value required";
- break;
- case XML_ERR_URI_FRAGMENT:
- errmsg = "Fragment not allowed";
- break;
- case XML_ERR_ATTLIST_NOT_STARTED:
- errmsg = "'(' required to start ATTLIST enumeration";
- break;
- case XML_ERR_NMTOKEN_REQUIRED:
- errmsg = "NmToken expected in ATTLIST enumeration";
- break;
- case XML_ERR_ATTLIST_NOT_FINISHED:
- errmsg = "')' required to finish ATTLIST enumeration";
- break;
- case XML_ERR_MIXED_NOT_STARTED:
- errmsg = "MixedContentDecl : '|' or ')*' expected";
- break;
- case XML_ERR_PCDATA_REQUIRED:
- errmsg = "MixedContentDecl : '#PCDATA' expected";
- break;
- case XML_ERR_ELEMCONTENT_NOT_STARTED:
- errmsg = "ContentDecl : Name or '(' expected";
- break;
- case XML_ERR_ELEMCONTENT_NOT_FINISHED:
- errmsg = "ContentDecl : ',' '|' or ')' expected";
- break;
- case XML_ERR_PEREF_IN_INT_SUBSET:
- errmsg =
- "PEReference: forbidden within markup decl in internal subset";
- break;
- case XML_ERR_GT_REQUIRED:
- errmsg = "expected '>'";
- break;
- case XML_ERR_CONDSEC_INVALID:
- errmsg = "XML conditional section '[' expected";
- break;
- case XML_ERR_EXT_SUBSET_NOT_FINISHED:
- errmsg = "Content error in the external subset";
- break;
- case XML_ERR_CONDSEC_INVALID_KEYWORD:
- errmsg =
- "conditional section INCLUDE or IGNORE keyword expected";
- break;
- case XML_ERR_CONDSEC_NOT_FINISHED:
- errmsg = "XML conditional section not closed";
- break;
- case XML_ERR_XMLDECL_NOT_STARTED:
- errmsg = "Text declaration '' expected";
- break;
- case XML_ERR_EXT_ENTITY_STANDALONE:
- errmsg = "external parsed entities cannot be standalone";
- break;
- case XML_ERR_ENTITYREF_SEMICOL_MISSING:
- errmsg = "EntityRef: expecting ';'";
- break;
- case XML_ERR_DOCTYPE_NOT_FINISHED:
- errmsg = "DOCTYPE improperly terminated";
- break;
- case XML_ERR_LTSLASH_REQUIRED:
- errmsg = "EndTag: '' not found";
- break;
- case XML_ERR_EQUAL_REQUIRED:
- errmsg = "expected '='";
- break;
- case XML_ERR_STRING_NOT_CLOSED:
- errmsg = "String not closed expecting \" or '";
- break;
- case XML_ERR_STRING_NOT_STARTED:
- errmsg = "String not started expecting ' or \"";
- break;
- case XML_ERR_ENCODING_NAME:
- errmsg = "Invalid XML encoding name";
- break;
- case XML_ERR_STANDALONE_VALUE:
- errmsg = "standalone accepts only 'yes' or 'no'";
- break;
- case XML_ERR_DOCUMENT_EMPTY:
- errmsg = "Document is empty";
- break;
- case XML_ERR_DOCUMENT_END:
- errmsg = "Extra content at the end of the document";
- break;
- case XML_ERR_NOT_WELL_BALANCED:
- errmsg = "chunk is not well balanced";
- break;
- case XML_ERR_EXTRA_CONTENT:
- errmsg = "extra content at the end of well balanced chunk";
- break;
- case XML_ERR_VERSION_MISSING:
- errmsg = "Malformed declaration expecting version";
- break;
- case XML_ERR_NAME_TOO_LONG:
- errmsg = "Name too long";
- break;
- case XML_ERR_INVALID_ENCODING:
- errmsg = "Invalid bytes in character encoding";
- break;
- case XML_IO_UNKNOWN:
- errmsg = "I/O error";
- break;
-#if 0
- case:
- errmsg = "";
- break;
-#endif
- default:
- errmsg = "Unregistered error message";
- }
- if (ctxt != NULL)
- ctxt->errNo = error;
if (info == NULL) {
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
- XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
- errmsg);
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, code, level,
+ NULL, NULL, NULL, 0, "%s\n", errmsg);
} else {
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
- XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
- errmsg, info);
- }
- if (ctxt != NULL) {
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0)
- ctxt->disableSAX = 1;
- }
-}
-
-/**
- * xmlErrEncodingInt:
- * @ctxt: an XML parser context
- * @error: the error number
- * @msg: the error message
- * @val: an integer value
- *
- * n encoding error
- */
-static void LIBXML_ATTR_FORMAT(3,0)
-xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
- const char *msg, int val)
-{
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if (ctxt != NULL)
- ctxt->errNo = error;
- __xmlRaiseError(NULL, NULL, NULL,
- ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
- NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
- if (ctxt != NULL) {
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0)
- ctxt->disableSAX = 1;
+ xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, code, level,
+ (const xmlChar *) info, NULL, NULL, 0,
+ "%s: %s\n", errmsg, info);
}
}
@@ -461,28 +414,8 @@ void
xmlHaltParser(xmlParserCtxtPtr ctxt) {
if (ctxt == NULL)
return;
- ctxt->instate = XML_PARSER_EOF;
- ctxt->disableSAX = 1;
- while (ctxt->inputNr > 1)
- xmlFreeInputStream(inputPop(ctxt));
- if (ctxt->input != NULL) {
- /*
- * in case there was a specific allocation deallocate before
- * overriding base
- */
- if (ctxt->input->free != NULL) {
- ctxt->input->free((xmlChar *) ctxt->input->base);
- ctxt->input->free = NULL;
- }
- if (ctxt->input->buf != NULL) {
- xmlFreeParserInputBuffer(ctxt->input->buf);
- ctxt->input->buf = NULL;
- }
- ctxt->input->cur = BAD_CAST"";
- ctxt->input->length = 0;
- ctxt->input->base = ctxt->input->cur;
- ctxt->input->end = ctxt->input->cur;
- }
+ ctxt->instate = XML_PARSER_EOF; /* TODO: Remove after refactoring */
+ ctxt->disableSAX = 2;
}
/**
@@ -511,14 +444,17 @@ int
xmlParserGrow(xmlParserCtxtPtr ctxt) {
xmlParserInputPtr in = ctxt->input;
xmlParserInputBufferPtr buf = in->buf;
- ptrdiff_t curEnd = in->end - in->cur;
- ptrdiff_t curBase = in->cur - in->base;
+ size_t curEnd = in->end - in->cur;
+ size_t curBase = in->cur - in->base;
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
+ XML_MAX_HUGE_LENGTH :
+ XML_MAX_LOOKUP_LIMIT;
int ret;
if (buf == NULL)
return(0);
/* Don't grow push parser buffer. */
- if ((ctxt->progressive) && (ctxt->inputNr <= 1))
+ if (PARSER_PROGRESSIVE(ctxt))
return(0);
/* Don't grow memory buffers. */
if ((buf->encoder == NULL) && (buf->readcallback == NULL))
@@ -526,10 +462,9 @@ xmlParserGrow(xmlParserCtxtPtr ctxt) {
if (buf->error != 0)
return(-1);
- if (((curEnd > XML_MAX_LOOKUP_LIMIT) ||
- (curBase > XML_MAX_LOOKUP_LIMIT)) &&
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
- xmlErrMemory(ctxt, "Huge input lookup");
+ if (curBase > maxLength) {
+ xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT,
+ "Buffer size limit exceeded, try XML_PARSE_HUGE\n");
xmlHaltParser(ctxt);
return(-1);
}
@@ -541,10 +476,7 @@ xmlParserGrow(xmlParserCtxtPtr ctxt) {
xmlBufUpdateInput(buf->buffer, in, curBase);
if (ret < 0) {
- xmlFatalErr(ctxt, buf->error, NULL);
- /* Buffer contents may be lost in case of memory errors. */
- if (buf->error == XML_ERR_NO_MEMORY)
- xmlHaltParser(ctxt);
+ xmlCtxtErrIO(ctxt, buf->error, NULL);
}
return(ret);
@@ -612,7 +544,7 @@ xmlParserShrink(xmlParserCtxtPtr ctxt) {
if (buf == NULL)
return;
/* Don't shrink pull parser memory buffers. */
- if (((ctxt->progressive == 0) || (ctxt->inputNr > 1)) &&
+ if ((!PARSER_PROGRESSIVE(ctxt)) &&
(buf->encoder == NULL) &&
(buf->readcallback == NULL))
return;
@@ -712,16 +644,14 @@ xmlNextChar(xmlParserCtxtPtr ctxt)
size_t avail;
int c;
- if ((ctxt == NULL) || (ctxt->instate == XML_PARSER_EOF) ||
- (ctxt->input == NULL))
+ if ((ctxt == NULL) || (ctxt->input == NULL))
return;
avail = ctxt->input->end - ctxt->input->cur;
if (avail < INPUT_CHUNK) {
xmlParserGrow(ctxt);
- if ((ctxt->instate == XML_PARSER_EOF) ||
- (ctxt->input->cur >= ctxt->input->end))
+ if (ctxt->input->cur >= ctxt->input->end)
return;
avail = ctxt->input->end - ctxt->input->cur;
}
@@ -788,21 +718,7 @@ xmlNextChar(xmlParserCtxtPtr ctxt)
encoding_error:
/* Only report the first error */
if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
- if ((ctxt == NULL) || (ctxt->input == NULL) ||
- (ctxt->input->end - ctxt->input->cur < 4)) {
- __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
- "Input is not proper UTF-8, indicate encoding !\n",
- NULL, NULL);
- } else {
- char buffer[150];
-
- snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- ctxt->input->cur[0], ctxt->input->cur[1],
- ctxt->input->cur[2], ctxt->input->cur[3]);
- __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
- "Input is not proper UTF-8, indicate encoding !\n%s",
- BAD_CAST buffer, NULL);
- }
+ xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
}
ctxt->input->cur++;
@@ -836,15 +752,11 @@ xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
int c;
if ((ctxt == NULL) || (len == NULL) || (ctxt->input == NULL)) return(0);
- if (ctxt->instate == XML_PARSER_EOF)
- return(0);
avail = ctxt->input->end - ctxt->input->cur;
if (avail < INPUT_CHUNK) {
xmlParserGrow(ctxt);
- if (ctxt->instate == XML_PARSER_EOF)
- return(0);
avail = ctxt->input->end - ctxt->input->cur;
}
@@ -879,8 +791,8 @@ xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
* TODO: Null bytes should be handled by callers,
* but this can be tricky.
*/
- xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
- "Char 0x0 out of allowed range\n", c);
+ xmlFatalErr(ctxt, XML_ERR_INVALID_CHAR,
+ "Char 0x0 out of allowed range\n");
}
} else {
*len = 1;
@@ -942,20 +854,7 @@ xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
encoding_error:
/* Only report the first error */
if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
- if (ctxt->input->end - ctxt->input->cur < 4) {
- __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
- "Input is not proper UTF-8, indicate encoding !\n",
- NULL, NULL);
- } else {
- char buffer[150];
-
- snprintf(&buffer[0], 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- ctxt->input->cur[0], ctxt->input->cur[1],
- ctxt->input->cur[2], ctxt->input->cur[3]);
- __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
- "Input is not proper UTF-8, indicate encoding !\n%s",
- BAD_CAST buffer, NULL);
- }
+ xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
}
*len = 1;
@@ -1029,9 +928,10 @@ xmlCopyCharMultiByte(xmlChar *out, int val) {
else if (val < 0x10000) { *out++= (val >> 12) | 0xE0; bits= 6;}
else if (val < 0x110000) { *out++= (val >> 18) | 0xF0; bits= 12; }
else {
- xmlErrEncodingInt(NULL, XML_ERR_INVALID_CHAR,
- "Internal error, xmlCopyCharMultiByte 0x%X out of bound\n",
- val);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ fprintf(stderr, "xmlCopyCharMultiByte: codepoint out of range\n");
+ abort();
+#endif
return(0);
}
for ( ; bits >= 0; bits-= 6)
@@ -1070,24 +970,30 @@ xmlCopyChar(int len ATTRIBUTE_UNUSED, xmlChar *out, int val) {
* *
************************************************************************/
-static xmlCharEncodingHandlerPtr
-xmlDetectEBCDIC(xmlParserInputPtr input) {
+static int
+xmlDetectEBCDIC(xmlParserInputPtr input, xmlCharEncodingHandlerPtr *hout) {
xmlChar out[200];
xmlCharEncodingHandlerPtr handler;
int inlen, outlen, res, i;
+ *hout = NULL;
+
/*
* To detect the EBCDIC code page, we convert the first 200 bytes
* to EBCDIC-US and try to find the encoding declaration.
*/
- handler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC);
- if (handler == NULL)
- return(NULL);
+ res = xmlLookupCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC, &handler);
+ if (res != 0)
+ return(res);
outlen = sizeof(out) - 1;
inlen = input->end - input->cur;
res = xmlEncInputChunk(handler, out, &outlen, input->cur, &inlen);
+ /*
+ * Return the EBCDIC handler if decoding failed. The error will
+ * be reported later.
+ */
if (res < 0)
- return(handler);
+ goto done;
out[outlen] = 0;
for (i = 0; i < outlen; i++) {
@@ -1119,15 +1025,25 @@ xmlDetectEBCDIC(xmlParserInputPtr input) {
break;
out[i] = 0;
xmlCharEncCloseFunc(handler);
- return(xmlFindCharEncodingHandler((char *) out + start));
+ res = xmlOpenCharEncodingHandler((char *) out + start,
+ /* output */ 0, &handler);
+ if (res != 0)
+ return(res);
+ *hout = handler;
+ return(0);
}
}
+done:
/*
- * ICU handlers are stateful, so we have to recreate them.
+ * Encoding handlers are stateful, so we have to recreate them.
*/
xmlCharEncCloseFunc(handler);
- return(xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC));
+ res = xmlLookupCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC, &handler);
+ if (res != 0)
+ return(res);
+ *hout = handler;
+ return(0);
}
/**
@@ -1135,10 +1051,11 @@ xmlDetectEBCDIC(xmlParserInputPtr input) {
* @ctxt: the parser context
* @enc: the encoding value (number)
*
- * Use encoding specified by enum to decode input data.
+ * Use encoding specified by enum to decode input data. This overrides
+ * the encoding found in the XML declaration.
*
- * This function can be used to enforce the encoding of chunks passed
- * to xmlParseChunk.
+ * This function can also be used to override the encoding of chunks
+ * passed to xmlParseChunk.
*
* Returns 0 in case of success, -1 otherwise
*/
@@ -1146,8 +1063,8 @@ int
xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
{
xmlCharEncodingHandlerPtr handler = NULL;
- int check = 1;
int ret;
+ int res;
if ((ctxt == NULL) || (ctxt->input == NULL))
return(-1);
@@ -1156,28 +1073,20 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
case XML_CHAR_ENCODING_NONE:
case XML_CHAR_ENCODING_UTF8:
case XML_CHAR_ENCODING_ASCII:
- check = 0;
+ res = 0;
break;
case XML_CHAR_ENCODING_EBCDIC:
- handler = xmlDetectEBCDIC(ctxt->input);
+ res = xmlDetectEBCDIC(ctxt->input, &handler);
break;
default:
- handler = xmlGetCharEncodingHandler(enc);
+ res = xmlLookupCharEncodingHandler(enc, &handler);
break;
}
- if ((check) && (handler == NULL)) {
+ if (res != 0) {
const char *name = xmlGetCharEncodingName(enc);
- __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
- "encoding not supported: %s\n",
- BAD_CAST (name ? name : ""), NULL);
- /*
- * TODO: We could recover from errors in external entities
- * if we didn't stop the parser. But most callers of this
- * function don't check the return value.
- */
- xmlStopParser(ctxt);
+ xmlFatalErr(ctxt, res, (name ? name : ""));
return(-1);
}
@@ -1191,8 +1100,59 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
}
/**
- * xmlSwitchInputEncoding:
+ * xmlSwitchEncodingName:
+ * @ctxt: the parser context, only for error reporting
+ * @input: the input strea,
+ * @encoding: the encoding name
+ *
+ * Available since 2.13.0.
+ *
+ * Returns 0 in case of success, -1 otherwise
+ */
+static int
+xmlSwitchInputEncodingName(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
+ const char *encoding) {
+ xmlCharEncodingHandlerPtr handler;
+ int res;
+
+ if (encoding == NULL)
+ return(-1);
+
+ res = xmlOpenCharEncodingHandler(encoding, /* output */ 0, &handler);
+ if (res != 0) {
+ xmlFatalErr(ctxt, res, encoding);
+ return(-1);
+ }
+
+ return(xmlSwitchInputEncoding(ctxt, input, handler));
+}
+
+/**
+ * xmlSwitchEncodingName:
* @ctxt: the parser context
+ * @encoding: the encoding name
+ *
+ * Use specified encoding to decode input data. This overrides the
+ * encoding found in the XML declaration.
+ *
+ * This function can also be used to override the encoding of chunks
+ * passed to xmlParseChunk.
+ *
+ * Available since 2.13.0.
+ *
+ * Returns 0 in case of success, -1 otherwise
+ */
+int
+xmlSwitchEncodingName(xmlParserCtxtPtr ctxt, const char *encoding) {
+ if (ctxt == NULL)
+ return(-1);
+
+ return(xmlSwitchInputEncodingName(ctxt, ctxt->input, encoding));
+}
+
+/**
+ * xmlSwitchInputEncoding:
+ * @ctxt: the parser context, only for error reporting
* @input: the input stream
* @handler: the encoding handler
*
@@ -1250,8 +1210,15 @@ xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
* Is there already some content down the pipe to convert ?
*/
if (xmlBufIsEmpty(in->buffer) == 0) {
+ xmlBufPtr buf;
size_t processed;
+ buf = xmlBufCreate();
+ if (buf == NULL) {
+ xmlCtxtErrMemory(ctxt);
+ return(-1);
+ }
+
/*
* Shrink the current input buffer.
* Move it as the raw buffer and create a new input buffer
@@ -1260,16 +1227,15 @@ xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
xmlBufShrink(in->buffer, processed);
input->consumed += processed;
in->raw = in->buffer;
- in->buffer = xmlBufCreate();
+ in->buffer = buf;
in->rawconsumed = processed;
nbchars = xmlCharEncInput(in);
xmlBufResetInput(in->buffer, input);
- if (nbchars < 0) {
- /* TODO: This could be an out of memory or an encoding error. */
- xmlErrInternal(ctxt,
- "switching encoding: encoder error\n",
- NULL);
+ if (nbchars == XML_ENC_ERR_MEMORY) {
+ xmlCtxtErrMemory(ctxt);
+ } else if (nbchars < 0) {
+ xmlCtxtErrIO(ctxt, in->error, NULL);
xmlHaltParser(ctxt);
return (-1);
}
@@ -1412,23 +1378,9 @@ xmlDetectEncoding(xmlParserCtxtPtr ctxt) {
*/
void
xmlSetDeclaredEncoding(xmlParserCtxtPtr ctxt, xmlChar *encoding) {
- if (ctxt->encoding != NULL)
- xmlFree((xmlChar *) ctxt->encoding);
- ctxt->encoding = encoding;
-
if (((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) &&
((ctxt->options & XML_PARSE_IGNORE_ENC) == 0)) {
- xmlCharEncodingHandlerPtr handler;
-
- handler = xmlFindCharEncodingHandler((const char *) encoding);
- if (handler == NULL) {
- __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
- "Unsupported encoding: %s\n",
- encoding, NULL);
- return;
- }
-
- xmlSwitchToEncoding(ctxt, handler);
+ xmlSwitchEncodingName(ctxt, (const char *) encoding);
ctxt->input->flags |= XML_INPUT_USES_ENC_DECL;
} else if (ctxt->input->flags & XML_INPUT_AUTO_ENCODING) {
static const char *allowedUTF8[] = {
@@ -1474,9 +1426,17 @@ xmlSetDeclaredEncoding(xmlParserCtxtPtr ctxt, xmlChar *encoding) {
"Encoding '%s' doesn't match "
"auto-detected '%s'\n",
encoding, BAD_CAST autoEnc);
+ xmlFree(encoding);
+ encoding = xmlStrdup(BAD_CAST autoEnc);
+ if (encoding == NULL)
+ xmlCtxtErrMemory(ctxt);
}
}
}
+
+ if (ctxt->encoding != NULL)
+ xmlFree((xmlChar *) ctxt->encoding);
+ ctxt->encoding = encoding;
}
/**
@@ -1520,7 +1480,6 @@ xmlFreeInputStream(xmlParserInputPtr input) {
if (input == NULL) return;
if (input->filename != NULL) xmlFree((char *) input->filename);
- if (input->directory != NULL) xmlFree((char *) input->directory);
if (input->version != NULL) xmlFree((char *) input->version);
if ((input->free != NULL) && (input->base != NULL))
input->free((xmlChar *) input->base);
@@ -1543,7 +1502,7 @@ xmlNewInputStream(xmlParserCtxtPtr ctxt) {
input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
if (input == NULL) {
- xmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
+ xmlCtxtErrMemory(ctxt);
return(NULL);
}
memset(input, 0, sizeof(xmlParserInput));
@@ -1557,7 +1516,7 @@ xmlNewInputStream(xmlParserCtxtPtr ctxt) {
*/
if (ctxt != NULL) {
if (input->id >= INT_MAX) {
- xmlErrMemory(ctxt, "Input ID overflow\n");
+ xmlCtxtErrMemory(ctxt);
return(NULL);
}
input->id = ctxt->input_id++;
@@ -1567,43 +1526,342 @@ xmlNewInputStream(xmlParserCtxtPtr ctxt) {
}
/**
- * xmlNewIOInputStream:
- * @ctxt: an XML parser context
- * @input: an I/O Input
- * @enc: the charset encoding if known
- *
- * Create a new input stream structure encapsulating the @input into
- * a stream suitable for the parser.
- *
- * Returns the new input stream or NULL
+ * xmlNewInputURL:
+ * @ctxt: parser context
+ * @url: filename or URL
+ * @publicId: publid ID from doctype (optional)
+ * @encoding: character encoding (optional)
+ * @flags: unused, pass 0
+ *
+ * Creates a new parser input from the filesystem, the network or
+ * a user-defined resource loader.
+ *
+ * @url is a filename or URL. If if contains the substring "://",
+ * it is assumed to be a Legacy Extended IRI. Otherwise, it is
+ * treated as a filesystem path.
+ *
+ * @publicId is an optional XML public ID, typically from a doctype
+ * declaration. It is used for catalog lookups.
+ *
+ * If @encoding is specified, it will override any encodings found
+ * in XML declarations, text declarations, BOMs, etc. Pass NULL
+ * for auto-detection.
+ *
+ * The following resource loaders will be called if they were
+ * registered (in order of precedence):
+ *
+ * - the global external entity loader set with
+ * xmlSetExternalEntityLoader
+ * - the per-thread xmlParserInputBufferCreateFilenameFunc set with
+ * xmlParserInputBufferCreateFilenameDefault
+ * - the default loader which will return
+ * - the result from a matching global input callback set with
+ * xmlRegisterInputCallbacks
+ * - a HTTP resource if support is compiled in.
+ * - a file opened from the filesystem, with automatic detection
+ * of compressed files if support is compiled in.
+ *
+ * The returned input can be passed to xmlCtxtParseDocument or
+ * htmlCtxtParseDocument.
+ *
+ * This function should not be invoked from user-defined resource
+ * loaders to avoid infinite loops.
+ *
+ * Returns a new parser input.
*/
xmlParserInputPtr
-xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
- xmlCharEncoding enc) {
- xmlParserInputPtr inputStream;
+xmlNewInputURL(xmlParserCtxtPtr ctxt, const char *url, const char *publicId,
+ const char *encoding, int flags ATTRIBUTE_UNUSED) {
+ xmlParserInputPtr input;
- if (input == NULL) return(NULL);
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
- inputStream = xmlNewInputStream(ctxt);
- if (inputStream == NULL) {
+ if ((ctxt == NULL) || (url == NULL))
return(NULL);
- }
- inputStream->filename = NULL;
- inputStream->buf = input;
- xmlBufResetInput(inputStream->buf->buffer, inputStream);
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
+ input = xmlLoadExternalEntity(url, publicId, ctxt);
+ if (input == NULL)
+ return(NULL);
- return(inputStream);
+ if (encoding != NULL)
+ xmlSwitchInputEncodingName(ctxt, input, encoding);
+
+ return(input);
}
/**
- * xmlNewEntityInputStream:
+ * xmlNewInputInternal:
+ * @ctxt: parser context
+ * @buf: parser input buffer
+ * @filename: filename or URL
+ * @encoding: character encoding (optional)
+ *
+ * Internal helper function.
+ *
+ * Returns a new parser input.
+ */
+static xmlParserInputPtr
+xmlNewInputInternal(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr buf,
+ const char *filename, const char *encoding) {
+ xmlParserInputPtr input;
+
+ input = xmlNewInputStream(ctxt);
+ if (input == NULL) {
+ xmlFreeParserInputBuffer(buf);
+ return(NULL);
+ }
+
+ input->buf = buf;
+ xmlBufResetInput(input->buf->buffer, input);
+
+ if (filename != NULL) {
+ input->filename = xmlMemStrdup(filename);
+ if (input->filename == NULL) {
+ xmlCtxtErrMemory(ctxt);
+ xmlFreeInputStream(input);
+ return(NULL);
+ }
+ }
+
+ if (encoding != NULL)
+ xmlSwitchInputEncodingName(ctxt, input, encoding);
+
+ return(input);
+}
+
+/**
+ * xmlNewInputMemory:
+ * @ctxt: parser context
+ * @url: base URL (optional)
+ * @mem: pointer to char array
+ * @size: size of array
+ * @encoding: character encoding (optional)
+ * @flags: optimization hints
+ *
+ * Creates a new parser input to read from a memory area.
+ *
+ * @url is used as base to resolve external entities and for
+ * error reporting.
+ *
+ * If the XML_INPUT_BUF_STATIC flag is set, the memory area must
+ * stay unchanged until parsing has finished. This can avoid
+ * temporary copies.
+ *
+ * If the XML_INPUT_BUF_ZERO_TERMINATED flag is set, the memory
+ * area must contain a zero byte after the buffer at position @size.
+ * This can avoid temporary copies.
+ *
+ * Returns a new parser input.
+ */
+xmlParserInputPtr
+xmlNewInputMemory(xmlParserCtxtPtr ctxt, const char *url,
+ const void *mem, size_t size,
+ const char *encoding, int flags) {
+ xmlParserInputBufferPtr buf;
+
+ if ((ctxt == NULL) || (mem == NULL))
+ return(NULL);
+
+ buf = xmlNewInputBufferMemory(mem, size, flags, XML_CHAR_ENCODING_NONE);
+ if (buf == NULL) {
+ xmlCtxtErrMemory(ctxt);
+ return(NULL);
+ }
+
+ return(xmlNewInputInternal(ctxt, buf, url, encoding));
+}
+
+/**
+ * xmlNewInputString:
+ * @ctxt: parser context
+ * @url: base URL (optional)
+ * @str: zero-terminated string
+ * @encoding: character encoding (optional)
+ * @flags: optimization hints
+ *
+ * Creates a new parser input to read from a zero-terminated string.
+ *
+ * @url is used as base to resolve external entities and for
+ * error reporting.
+ *
+ * If the XML_INPUT_BUF_STATIC flag is set, the string must
+ * stay unchanged until parsing has finished. This can avoid
+ * temporary copies.
+ *
+ * Returns a new parser input.
+ */
+xmlParserInputPtr
+xmlNewInputString(xmlParserCtxtPtr ctxt, const char *url,
+ const char *str, const char *encoding, int flags) {
+ xmlParserInputBufferPtr buf;
+
+ if ((ctxt == NULL) || (str == NULL))
+ return(NULL);
+
+ buf = xmlNewInputBufferString(str, flags);
+ if (buf == NULL) {
+ xmlCtxtErrMemory(ctxt);
+ return(NULL);
+ }
+
+ return(xmlNewInputInternal(ctxt, buf, url, encoding));
+}
+
+/**
+ * xmlNewInputFd:
+ * @ctxt: parser context
+ * @url: base URL (optional)
+ * @fd: file descriptor
+ * @encoding: character encoding (optional)
+ * @flags: unused, pass 0
+ *
+ * Creates a new parser input to read from a zero-terminated string.
+ *
+ * @url is used as base to resolve external entities and for
+ * error reporting.
+ *
+ * @fd is closed after parsing has finished.
+ *
+ * Returns a new parser input.
+ */
+xmlParserInputPtr
+xmlNewInputFd(xmlParserCtxtPtr ctxt, const char *url,
+ int fd, const char *encoding, int flags ATTRIBUTE_UNUSED) {
+ xmlParserInputBufferPtr buf;
+
+ if ((ctxt == NULL) || (fd < 0))
+ return(NULL);
+
+ buf = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
+ if (buf == NULL) {
+ xmlCtxtErrMemory(ctxt);
+ return(NULL);
+ }
+
+ return(xmlNewInputInternal(ctxt, buf, url, encoding));
+}
+
+/**
+ * xmlNewInputIO:
+ * @ctxt: parser context
+ * @url: base URL (optional)
+ * @ioRead: read callback
+ * @ioClose: close callback (optional)
+ * @ioCtxt: IO context
+ * @encoding: character encoding (optional)
+ * @flags: unused, pass 0
+ *
+ * Creates a new parser input to read from input callbacks and
+ * cintext.
+ *
+ * @url is used as base to resolve external entities and for
+ * error reporting.
+ *
+ * @ioRead is called to read new data into a provided buffer.
+ * It must return the number of bytes written into the buffer
+ * ot a negative xmlParserErrors code on failure.
+ *
+ * @ioClose is called after parsing has finished.
+ *
+ * @ioCtxt is an opaque pointer passed to the callbacks.
+ *
+ * Returns a new parser input.
+ */
+xmlParserInputPtr
+xmlNewInputIO(xmlParserCtxtPtr ctxt, const char *url,
+ xmlInputReadCallback ioRead, xmlInputCloseCallback ioClose,
+ void *ioCtxt,
+ const char *encoding, int flags ATTRIBUTE_UNUSED) {
+ xmlParserInputBufferPtr buf;
+
+ if ((ctxt == NULL) || (ioRead == NULL))
+ return(NULL);
+
+ buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
+ if (buf == NULL) {
+ xmlCtxtErrMemory(ctxt);
+ if (ioClose != NULL)
+ ioClose(ioCtxt);
+ return(NULL);
+ }
+
+ buf->context = ioCtxt;
+ buf->readcallback = ioRead;
+ buf->closecallback = ioClose;
+
+ return(xmlNewInputInternal(ctxt, buf, url, encoding));
+}
+
+/**
+ * xmlNewInputPush:
+ * @ctxt: parser context
+ * @url: base URL (optional)
+ * @chunk: pointer to char array
+ * @size: size of array
+ * @encoding: character encoding (optional)
+ *
+ * Creates a new parser input for a push parser.
+ *
+ * Returns a new parser input.
+ */
+xmlParserInputPtr
+xmlNewInputPush(xmlParserCtxtPtr ctxt, const char *url,
+ const char *chunk, int size, const char *encoding) {
+ xmlParserInputBufferPtr buf;
+ xmlParserInputPtr input;
+
+ buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
+ if (buf == NULL) {
+ xmlCtxtErrMemory(ctxt);
+ return(NULL);
+ }
+
+ input = xmlNewInputInternal(ctxt, buf, url, encoding);
+ if (input == NULL)
+ return(NULL);
+
+ input->flags |= XML_INPUT_PROGRESSIVE;
+
+ if ((size > 0) && (chunk != NULL)) {
+ int res;
+
+ res = xmlParserInputBufferPush(input->buf, size, chunk);
+ xmlBufResetInput(input->buf->buffer, input);
+ if (res < 0) {
+ xmlCtxtErrIO(ctxt, input->buf->error, NULL);
+ xmlFreeInputStream(input);
+ return(NULL);
+ }
+ }
+
+ return(input);
+}
+
+/**
+ * xmlNewIOInputStream:
* @ctxt: an XML parser context
- * @entity: an Entity pointer
+ * @buf: an input buffer
+ * @enc: the charset encoding if known
+ *
+ * Create a new input stream structure encapsulating the @input into
+ * a stream suitable for the parser.
+ *
+ * Returns the new input stream or NULL
+ */
+xmlParserInputPtr
+xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr buf,
+ xmlCharEncoding enc) {
+ const char *encoding;
+
+ if (buf == NULL)
+ return(NULL);
+
+ encoding = xmlGetCharEncodingName(enc);
+ return(xmlNewInputInternal(ctxt, buf, NULL, encoding));
+}
+
+/**
+ * xmlNewEntityInputStream:
+ * @ctxt: an XML parser context
+ * @ent: an Entity pointer
*
* DEPRECATED: Internal function, do not use.
*
@@ -1612,61 +1870,27 @@ xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
* Returns the new input stream or NULL
*/
xmlParserInputPtr
-xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
xmlParserInputPtr input;
- if (entity == NULL) {
- xmlErrInternal(ctxt, "xmlNewEntityInputStream entity = NULL\n",
- NULL);
- return(NULL);
- }
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "new input from entity: %s\n", entity->name);
- if (entity->content == NULL) {
- switch (entity->etype) {
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- xmlErrInternal(ctxt, "Cannot parse entity %s\n",
- entity->name);
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- case XML_EXTERNAL_PARAMETER_ENTITY:
- input = xmlLoadExternalEntity((char *) entity->URI,
- (char *) entity->ExternalID, ctxt);
- if (input != NULL)
- input->entity = entity;
- return(input);
- case XML_INTERNAL_GENERAL_ENTITY:
- xmlErrInternal(ctxt,
- "Internal entity %s without content !\n",
- entity->name);
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- xmlErrInternal(ctxt,
- "Internal parameter entity %s without content !\n",
- entity->name);
- break;
- case XML_INTERNAL_PREDEFINED_ENTITY:
- xmlErrInternal(ctxt,
- "Predefined entity %s without content !\n",
- entity->name);
- break;
- }
- return(NULL);
- }
- input = xmlNewInputStream(ctxt);
- if (input == NULL) {
+ if ((ctxt == NULL) || (ent == NULL))
return(NULL);
+
+ if (ent->content != NULL) {
+ input = xmlNewInputString(ctxt, NULL, (const char *) ent->content,
+ NULL, XML_INPUT_BUF_STATIC);
+ } else if (ent->URI != NULL) {
+ input = xmlLoadExternalEntity((char *) ent->URI,
+ (char *) ent->ExternalID, ctxt);
+ } else {
+ return(NULL);
}
- if (entity->URI != NULL)
- input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
- input->base = entity->content;
- if (entity->length == 0)
- entity->length = xmlStrlen(entity->content);
- input->cur = entity->content;
- input->length = entity->length;
- input->end = &entity->content[input->length];
- input->entity = entity;
+
+ if (input == NULL)
+ return(NULL);
+
+ input->entity = ent;
+
return(input);
}
@@ -1676,35 +1900,159 @@ xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
* @buffer: an memory buffer
*
* Create a new input stream based on a memory buffer.
+ *
* Returns the new input stream
*/
xmlParserInputPtr
xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
- xmlParserInputPtr input;
- xmlParserInputBufferPtr buf;
+ return(xmlNewInputString(ctxt, NULL, (const char *) buffer, NULL, 0));
+}
- if (buffer == NULL) {
- xmlErrInternal(ctxt, "xmlNewStringInputStream string = NULL\n",
- NULL);
- return(NULL);
- }
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "new fixed input: %.30s\n", buffer);
- buf = xmlParserInputBufferCreateString(buffer);
- if (buf == NULL) {
- xmlErrMemory(ctxt, NULL);
- return(NULL);
+
+/****************************************************************
+ * *
+ * External entities loading *
+ * *
+ ****************************************************************/
+
+#ifdef LIBXML_CATALOG_ENABLED
+
+/**
+ * xmlResolveResourceFromCatalog:
+ * @URL: the URL for the entity to load
+ * @ID: the System ID for the entity to load
+ * @ctxt: the context in which the entity is called or NULL
+ *
+ * Resolves the URL and ID against the appropriate catalog.
+ * This function is used by xmlDefaultExternalEntityLoader and
+ * xmlNoNetExternalEntityLoader.
+ *
+ * Returns a new allocated URL, or NULL.
+ */
+static xmlChar *
+xmlResolveResourceFromCatalog(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt) {
+ xmlChar *resource = NULL;
+ xmlCatalogAllow pref;
+
+ /*
+ * If the resource doesn't exists as a file,
+ * try to load it from the resource pointed in the catalogs
+ */
+ pref = xmlCatalogGetDefaults();
+
+ if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) {
+ /*
+ * Do a local lookup
+ */
+ if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
+ ((pref == XML_CATA_ALLOW_ALL) ||
+ (pref == XML_CATA_ALLOW_DOCUMENT))) {
+ resource = xmlCatalogLocalResolve(ctxt->catalogs,
+ (const xmlChar *)ID,
+ (const xmlChar *)URL);
+ }
+ /*
+ * Try a global lookup
+ */
+ if ((resource == NULL) &&
+ ((pref == XML_CATA_ALLOW_ALL) ||
+ (pref == XML_CATA_ALLOW_GLOBAL))) {
+ resource = xmlCatalogResolve((const xmlChar *)ID,
+ (const xmlChar *)URL);
+ }
+ if ((resource == NULL) && (URL != NULL))
+ resource = xmlStrdup((const xmlChar *) URL);
+
+ /*
+ * TODO: do an URI lookup on the reference
+ */
+ if ((resource != NULL) && (!xmlNoNetExists((const char *)resource))) {
+ xmlChar *tmp = NULL;
+
+ if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
+ ((pref == XML_CATA_ALLOW_ALL) ||
+ (pref == XML_CATA_ALLOW_DOCUMENT))) {
+ tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource);
+ }
+ if ((tmp == NULL) &&
+ ((pref == XML_CATA_ALLOW_ALL) ||
+ (pref == XML_CATA_ALLOW_GLOBAL))) {
+ tmp = xmlCatalogResolveURI(resource);
+ }
+
+ if (tmp != NULL) {
+ xmlFree(resource);
+ resource = tmp;
+ }
+ }
}
- input = xmlNewInputStream(ctxt);
- if (input == NULL) {
- xmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
- xmlFreeParserInputBuffer(buf);
- return(NULL);
+
+ return resource;
+}
+
+#endif
+
+/**
+ * xmlCheckHTTPInput:
+ * @ctxt: an XML parser context
+ * @ret: an XML parser input
+ *
+ * DEPRECATED: Internal function, don't use.
+ *
+ * Check an input in case it was created from an HTTP stream, in that
+ * case it will handle encoding and update of the base URL in case of
+ * redirection. It also checks for HTTP errors in which case the input
+ * is cleanly freed up and an appropriate error is raised in context
+ *
+ * Returns the input or NULL in case of HTTP error.
+ */
+xmlParserInputPtr
+xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) {
+ /* Avoid unused variable warning if features are disabled. */
+ (void) ctxt;
+
+#ifdef LIBXML_HTTP_ENABLED
+ if ((ret != NULL) && (ret->buf != NULL) &&
+ (ret->buf->readcallback == xmlIOHTTPRead) &&
+ (ret->buf->context != NULL)) {
+ const char *encoding;
+ const char *redir;
+ const char *mime;
+ int code;
+
+ code = xmlNanoHTTPReturnCode(ret->buf->context);
+ if (code >= 400) {
+ /* fatal error */
+ if (ret->filename != NULL)
+ xmlCtxtErrIO(ctxt, XML_IO_LOAD_ERROR, ret->filename);
+ else
+ xmlCtxtErrIO(ctxt, XML_IO_LOAD_ERROR, "");
+ xmlFreeInputStream(ret);
+ ret = NULL;
+ } else {
+
+ mime = xmlNanoHTTPMimeType(ret->buf->context);
+ if ((xmlStrstr(BAD_CAST mime, BAD_CAST "/xml")) ||
+ (xmlStrstr(BAD_CAST mime, BAD_CAST "+xml"))) {
+ encoding = xmlNanoHTTPEncoding(ret->buf->context);
+ if (encoding != NULL)
+ xmlSwitchEncodingName(ctxt, encoding);
+#if 0
+ } else if (xmlStrstr(BAD_CAST mime, BAD_CAST "html")) {
+#endif
+ }
+ redir = xmlNanoHTTPRedir(ret->buf->context);
+ if (redir != NULL) {
+ if (ret->filename != NULL)
+ xmlFree((xmlChar *) ret->filename);
+ ret->filename =
+ (char *) xmlStrdup((const xmlChar *) redir);
+ }
+ }
}
- input->buf = buf;
- xmlBufResetInput(input->buf->buffer, input);
- return(input);
+#endif
+ return(ret);
}
/**
@@ -1720,22 +2068,17 @@ xmlParserInputPtr
xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
xmlParserInputBufferPtr buf;
xmlParserInputPtr inputStream;
- char *directory = NULL;
- xmlChar *URI = NULL;
-
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "new input from file: %s\n", filename);
- if (ctxt == NULL) return(NULL);
- buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
+ const xmlChar *URI;
+ xmlChar *canonic;
+ int code;
+
+ if ((ctxt == NULL) || (filename == NULL))
+ return(NULL);
+
+ code = xmlParserInputBufferCreateFilenameSafe(filename,
+ XML_CHAR_ENCODING_NONE, &buf);
if (buf == NULL) {
- if (filename == NULL)
- __xmlLoaderErr(ctxt,
- "failed to load external entity: NULL filename \n",
- NULL);
- else
- __xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n",
- (const char *) filename);
+ xmlCtxtErrIO(ctxt, code, filename);
return(NULL);
}
@@ -1751,21 +2094,168 @@ xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
return(NULL);
if (inputStream->filename == NULL)
- URI = xmlStrdup((xmlChar *) filename);
+ URI = (xmlChar *) filename;
else
- URI = xmlStrdup((xmlChar *) inputStream->filename);
- directory = xmlParserGetDirectory((const char *) URI);
- if (inputStream->filename != NULL) xmlFree((char *)inputStream->filename);
- inputStream->filename = (char *) xmlCanonicPath((const xmlChar *) URI);
- if (URI != NULL) xmlFree((char *) URI);
- inputStream->directory = directory;
+ URI = (xmlChar *) inputStream->filename;
+ canonic = xmlCanonicPath(URI);
+ if (canonic == NULL) {
+ xmlCtxtErrMemory(ctxt);
+ xmlFreeInputStream(inputStream);
+ return(NULL);
+ }
+ if (inputStream->filename != NULL)
+ xmlFree((char *) inputStream->filename);
+ inputStream->filename = (char *) canonic;
xmlBufResetInput(inputStream->buf->buffer, inputStream);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
+
return(inputStream);
}
+/**
+ * xmlDefaultExternalEntityLoader:
+ * @URL: the URL for the entity to load
+ * @ID: the System ID for the entity to load
+ * @ctxt: the context in which the entity is called or NULL
+ *
+ * By default we don't load external entities, yet.
+ *
+ * Returns a new allocated xmlParserInputPtr, or NULL.
+ */
+static xmlParserInputPtr
+xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt)
+{
+ xmlParserInputPtr ret = NULL;
+ xmlChar *resource = NULL;
+
+ if (URL == NULL)
+ return(NULL);
+
+ if ((ctxt != NULL) && (ctxt->options & XML_PARSE_NONET)) {
+ int options = ctxt->options;
+
+ ctxt->options -= XML_PARSE_NONET;
+ ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+ ctxt->options = options;
+ return(ret);
+ }
+#ifdef LIBXML_CATALOG_ENABLED
+ resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
+#endif
+
+ if (resource == NULL)
+ resource = (xmlChar *) URL;
+
+ ret = xmlNewInputFromFile(ctxt, (const char *) resource);
+ if ((resource != NULL) && (resource != (xmlChar *) URL))
+ xmlFree(resource);
+ return (ret);
+}
+
+/**
+ * xmlNoNetExternalEntityLoader:
+ * @URL: the URL for the entity to load
+ * @ID: the System ID for the entity to load
+ * @ctxt: the context in which the entity is called or NULL
+ *
+ * A specific entity loader disabling network accesses, though still
+ * allowing local catalog accesses for resolution.
+ *
+ * Returns a new allocated xmlParserInputPtr, or NULL.
+ */
+xmlParserInputPtr
+xmlNoNetExternalEntityLoader(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt) {
+ xmlParserInputPtr input = NULL;
+ xmlChar *resource = NULL;
+
+#ifdef LIBXML_CATALOG_ENABLED
+ resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
+#endif
+
+ if (resource == NULL)
+ resource = (xmlChar *) URL;
+
+ if (resource != NULL) {
+ if ((!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "ftp://", 6)) ||
+ (!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "http://", 7))) {
+ xmlCtxtErrIO(ctxt, XML_IO_NETWORK_ATTEMPT,
+ (const char *) resource);
+ /*
+ * Also forward the error directly to the global error
+ * handler, which the XML::LibXML test suite expects.
+ */
+ __xmlIOErr(XML_FROM_IO, XML_IO_NETWORK_ATTEMPT,
+ (const char *) resource);
+ if (resource != (xmlChar *) URL)
+ xmlFree(resource);
+ return(NULL);
+ }
+ }
+ input = xmlDefaultExternalEntityLoader((const char *) resource, ID, ctxt);
+ if (resource != (xmlChar *) URL)
+ xmlFree(resource);
+ return(input);
+}
+
+/*
+ * This global has to die eventually
+ */
+static xmlExternalEntityLoader
+xmlCurrentExternalEntityLoader = xmlDefaultExternalEntityLoader;
+
+/**
+ * xmlSetExternalEntityLoader:
+ * @f: the new entity resolver function
+ *
+ * Changes the defaultexternal entity resolver function for the application
+ */
+void
+xmlSetExternalEntityLoader(xmlExternalEntityLoader f) {
+ xmlCurrentExternalEntityLoader = f;
+}
+
+/**
+ * xmlGetExternalEntityLoader:
+ *
+ * Get the default external entity resolver function for the application
+ *
+ * Returns the xmlExternalEntityLoader function pointer
+ */
+xmlExternalEntityLoader
+xmlGetExternalEntityLoader(void) {
+ return(xmlCurrentExternalEntityLoader);
+}
+
+/**
+ * xmlLoadExternalEntity:
+ * @URL: the URL for the entity to load
+ * @ID: the Public ID for the entity to load
+ * @ctxt: the context in which the entity is called or NULL
+ *
+ * Returns the xmlParserInputPtr or NULL
+ */
+xmlParserInputPtr
+xmlLoadExternalEntity(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt) {
+ char *canonicFilename;
+ xmlParserInputPtr ret;
+
+ if (URL == NULL)
+ return(NULL);
+
+ canonicFilename = (char *) xmlCanonicPath((const xmlChar *) URL);
+ if (canonicFilename == NULL) {
+ xmlCtxtErrMemory(ctxt);
+ return(NULL);
+ }
+
+ ret = xmlCurrentExternalEntityLoader(canonicFilename, ID, ctxt);
+ xmlFree(canonicFilename);
+ return(ret);
+}
+
/************************************************************************
* *
* Commodity functions to handle parser contexts *
@@ -1789,27 +2279,19 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
{
xmlParserInputPtr input;
- if(ctxt==NULL) {
- xmlErrInternal(NULL, "Got NULL parser context\n", NULL);
+ if (ctxt == NULL)
return(-1);
- }
-
- xmlInitParser();
if (ctxt->dict == NULL)
ctxt->dict = xmlDictCreate();
- if (ctxt->dict == NULL) {
- xmlErrMemory(NULL, "cannot initialize parser context\n");
+ if (ctxt->dict == NULL)
return(-1);
- }
xmlDictSetLimit(ctxt->dict, XML_MAX_DICTIONARY_LIMIT);
if (ctxt->sax == NULL)
ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
- if (ctxt->sax == NULL) {
- xmlErrMemory(NULL, "cannot initialize parser context\n");
+ if (ctxt->sax == NULL)
return(-1);
- }
if (sax == NULL) {
memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
xmlSAXVersion(ctxt->sax, 2);
@@ -1832,13 +2314,8 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
xmlMalloc(5 * sizeof(xmlParserInputPtr));
ctxt->inputMax = 5;
}
- if (ctxt->inputTab == NULL) {
- xmlErrMemory(NULL, "cannot initialize parser context\n");
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
+ if (ctxt->inputTab == NULL)
return(-1);
- }
while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
xmlFreeInputStream(input);
}
@@ -1851,26 +2328,15 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
ctxt->hasExternalSubset = 0;
ctxt->hasPErefs = 0;
ctxt->html = 0;
- ctxt->external = 0;
ctxt->instate = XML_PARSER_START;
- ctxt->token = 0;
- ctxt->directory = NULL;
/* Allocate the Node stack */
if (ctxt->nodeTab == NULL) {
ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
ctxt->nodeMax = 10;
}
- if (ctxt->nodeTab == NULL) {
- xmlErrMemory(NULL, "cannot initialize parser context\n");
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
+ if (ctxt->nodeTab == NULL)
return(-1);
- }
ctxt->nodeNr = 0;
ctxt->node = NULL;
@@ -1879,19 +2345,8 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
ctxt->nameMax = 10;
}
- if (ctxt->nameTab == NULL) {
- xmlErrMemory(NULL, "cannot initialize parser context\n");
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
- ctxt->nameNr = 0;
- ctxt->nameMax = 0;
- ctxt->name = NULL;
+ if (ctxt->nameTab == NULL)
return(-1);
- }
ctxt->nameNr = 0;
ctxt->name = NULL;
@@ -1900,22 +2355,8 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
ctxt->spaceMax = 10;
}
- if (ctxt->spaceTab == NULL) {
- xmlErrMemory(NULL, "cannot initialize parser context\n");
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
- ctxt->nameNr = 0;
- ctxt->nameMax = 0;
- ctxt->name = NULL;
- ctxt->spaceNr = 0;
- ctxt->spaceMax = 0;
- ctxt->space = NULL;
+ if (ctxt->spaceTab == NULL)
return(-1);
- }
ctxt->spaceNr = 1;
ctxt->spaceMax = 10;
ctxt->spaceTab[0] = -1;
@@ -1924,11 +2365,23 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
ctxt->wellFormed = 1;
ctxt->nsWellFormed = 1;
ctxt->valid = 1;
+
+ ctxt->options = XML_PARSE_NODICT;
+
+ /*
+ * Initialize some parser options from deprecated global variables.
+ * Note that the "modern" API taking options arguments or
+ * xmlCtxtSetOptions will ignore these defaults. They're only
+ * relevant if old API functions like xmlParseFile are used.
+ */
ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
if (ctxt->loadsubset) {
ctxt->options |= XML_PARSE_DTDLOAD;
}
ctxt->validate = xmlDoValidityCheckingDefaultValue;
+ if (ctxt->validate) {
+ ctxt->options |= XML_PARSE_DTDVALID;
+ }
ctxt->pedantic = xmlPedanticParserDefaultValue;
if (ctxt->pedantic) {
ctxt->options |= XML_PARSE_PEDANTIC;
@@ -1939,23 +2392,18 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
ctxt->options |= XML_PARSE_NOBLANKS;
}
+ ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
+ if (ctxt->replaceEntities) {
+ ctxt->options |= XML_PARSE_NOENT;
+ }
+ if (xmlGetWarningsDefaultValue == 0)
+ ctxt->options |= XML_PARSE_NOWARNING;
ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
ctxt->vctxt.userData = ctxt;
ctxt->vctxt.error = xmlParserValidityError;
ctxt->vctxt.warning = xmlParserValidityWarning;
- if (ctxt->validate) {
- if (xmlGetWarningsDefaultValue == 0)
- ctxt->vctxt.warning = NULL;
- else
- ctxt->vctxt.warning = xmlParserValidityWarning;
- ctxt->vctxt.nodeMax = 0;
- ctxt->options |= XML_PARSE_DTDVALID;
- }
- ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
- if (ctxt->replaceEntities) {
- ctxt->options |= XML_PARSE_NOENT;
- }
+
ctxt->record_info = 0;
ctxt->checkIndex = 0;
ctxt->inSubset = 0;
@@ -1971,7 +2419,7 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
if (ctxt->nsdb == NULL) {
ctxt->nsdb = xmlParserNsCreate();
if (ctxt->nsdb == NULL) {
- xmlErrMemory(ctxt, NULL);
+ xmlCtxtErrMemory(ctxt);
return(-1);
}
}
@@ -2031,7 +2479,6 @@ xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
if (ctxt->sax != NULL)
#endif /* LIBXML_SAX1_ENABLED */
xmlFree(ctxt->sax);
- if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
if (ctxt->atts != NULL) xmlFree((xmlChar * *)ctxt->atts);
if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
@@ -2107,6 +2554,10 @@ xmlNewParserCtxt(void)
* Allocate and initialize a new SAX parser context. If userData is NULL,
* the parser context will be passed as user data.
*
+ * Available since 2.11.0. If you want support older versions,
+ * it's best to invoke xmlNewParserCtxt and set ctxt->sax with
+ * struct assignment.
+ *
* Returns the xmlParserCtxtPtr or NULL if memory allocation failed.
*/
@@ -2115,11 +2566,11 @@ xmlNewSAXParserCtxt(const xmlSAXHandler *sax, void *userData)
{
xmlParserCtxtPtr ctxt;
+ xmlInitParser();
+
ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
- if (ctxt == NULL) {
- xmlErrMemory(NULL, "cannot allocate parser context\n");
+ if (ctxt == NULL)
return(NULL);
- }
memset(ctxt, 0, sizeof(xmlParserCtxt));
if (xmlInitSAXParserCtxt(ctxt, sax, userData) < 0) {
xmlFreeParserCtxt(ctxt);
@@ -2163,7 +2614,7 @@ xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
* Returns an xmlParserNodeInfo block pointer or NULL
*/
const xmlParserNodeInfo *
-xmlParserFindNodeInfo(const xmlParserCtxtPtr ctx, const xmlNodePtr node)
+xmlParserFindNodeInfo(xmlParserCtxtPtr ctx, xmlNodePtr node)
{
unsigned long pos;
@@ -2229,8 +2680,8 @@ xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
* Returns a long indicating the position of the record
*/
unsigned long
-xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
- const xmlNodePtr node)
+xmlParserFindNodeInfoIndex(xmlParserNodeInfoSeqPtr seq,
+ xmlNodePtr node)
{
unsigned long upper, lower, middle;
int found = 0;
@@ -2271,7 +2722,7 @@ xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
*/
void
xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
- const xmlParserNodeInfoPtr info)
+ xmlParserNodeInfoPtr info)
{
unsigned long pos;
@@ -2307,7 +2758,7 @@ xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
byte_size);
if (tmp_buffer == NULL) {
- xmlErrMemory(ctxt, "failed to allocate buffer\n");
+ xmlCtxtErrMemory(ctxt);
return;
}
ctxt->node_seq.buffer = tmp_buffer;
diff --git a/pattern.c b/pattern.c
index 55ae2d3..23b5274 100644
--- a/pattern.c
+++ b/pattern.c
@@ -344,9 +344,8 @@ xmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
* Returns -1 in case of failure, 0 otherwise.
*/
static int
-xmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
- xmlPatternPtr comp,
- xmlPatOp op, xmlChar * value, xmlChar * value2)
+xmlPatternAdd(xmlPatParserContextPtr ctxt, xmlPatternPtr comp,
+ xmlPatOp op, xmlChar * value, xmlChar * value2)
{
if (comp->nbStep >= comp->maxStep) {
xmlStepOpPtr temp;
@@ -355,6 +354,7 @@ xmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
if (temp == NULL) {
ERROR(ctxt, NULL, NULL,
"xmlPatternAdd: realloc failed\n");
+ ctxt->error = -1;
return (-1);
}
comp->steps = temp;
@@ -697,10 +697,6 @@ xmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {
* *
************************************************************************/
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
#define CUR (*ctxt->cur)
#define SKIP(val) ctxt->cur += (val)
#define NXT(val) ctxt->cur[(val)]
@@ -717,14 +713,6 @@ xmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {
#define PUSH(op, val, val2) \
if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
-#define XSLT_ERROR(X) \
- { xsltError(ctxt, __FILE__, __LINE__, X); \
- ctxt->error = (X); return; }
-
-#define XSLT_ERROR0(X) \
- { xsltError(ctxt, __FILE__, __LINE__, X); \
- ctxt->error = (X); return(0); }
-
#if 0
/**
* xmlPatScanLiteral:
@@ -869,6 +857,8 @@ xmlPatScanNCName(xmlPatParserContextPtr ctxt) {
ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
else
ret = xmlStrndup(q, cur - q);
+ if (ret == NULL)
+ ctxt->error = -1;
CUR_PTR = cur;
return(ret);
}
@@ -913,6 +903,8 @@ xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
SKIP_BLANKS;
name = xmlPatScanNCName(ctxt);
+ if (ctxt->error < 0)
+ return;
if (name == NULL) {
if (CUR == '*') {
PUSH(XML_OP_ATTR, NULL, NULL);
@@ -1032,6 +1024,8 @@ xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
return;
}
name = xmlPatScanNCName(ctxt);
+ if (ctxt->error < 0)
+ return;
if (name == NULL) {
if (CUR == '*') {
NEXT;
@@ -1248,6 +1242,8 @@ xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
if (CUR == '@') {
NEXT;
xmlCompileAttributeTest(ctxt);
+ if (ctxt->error != 0)
+ goto error;
SKIP_BLANKS;
/* TODO: check for incompleteness */
if (CUR != 0) {
@@ -1788,7 +1784,7 @@ static int
xmlStreamPushInternal(xmlStreamCtxtPtr stream,
const xmlChar *name, const xmlChar *ns,
int nodeType) {
- int ret = 0, err = 0, final = 0, tmp, i, m, match, stepNr, desc;
+ int ret = 0, final = 0, tmp, i, m, match, stepNr, desc;
xmlStreamCompPtr comp;
xmlStreamStep step;
@@ -1819,10 +1815,8 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
*/
ret = 1;
} else if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
- /* TODO: Do we need this ? */
- tmp = xmlStreamCtxtAddState(stream, 0, 0);
- if (tmp < 0)
- err++;
+ if (xmlStreamCtxtAddState(stream, 0, 0) < 0)
+ return(-1);
}
}
}
@@ -1977,9 +1971,9 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
final = step.flags & XML_STREAM_STEP_FINAL;
if (final) {
ret = 1;
- } else {
- xmlStreamCtxtAddState(stream, stepNr + 1,
- stream->level + 1);
+ } else if (xmlStreamCtxtAddState(stream, stepNr + 1,
+ stream->level + 1) < 0) {
+ return(-1);
}
if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
/*
@@ -2081,10 +2075,11 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
}
final = step.flags & XML_STREAM_STEP_FINAL;
if (match) {
- if (final)
+ if (final) {
ret = 1;
- else
- xmlStreamCtxtAddState(stream, 1, stream->level);
+ } else if (xmlStreamCtxtAddState(stream, 1, stream->level) < 0) {
+ return(-1);
+ }
if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
/*
* Check if we have a special case like "foo//.", where
@@ -2106,8 +2101,6 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
stream = stream->next;
} /* while stream != NULL */
- if (err > 0)
- ret = -1;
return(ret);
}
@@ -2259,28 +2252,37 @@ xmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt)
************************************************************************/
/**
- * xmlPatterncompile:
+ * xmlPatternCompileSafe:
* @pattern: the pattern to compile
* @dict: an optional dictionary for interned strings
* @flags: compilation flags, see xmlPatternFlags
* @namespaces: the prefix definitions, array of [URI, prefix] or NULL
+ * @patternOut: output pattern
*
* Compile a pattern.
*
- * Returns the compiled form of the pattern or NULL in case of error
+ * Available since 2.13.0.
+ *
+ * Returns 0 on success, 1 on error, -1 if a memory allocation failed.
*/
-xmlPatternPtr
-xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
- const xmlChar **namespaces) {
+int
+xmlPatternCompileSafe(const xmlChar *pattern, xmlDict *dict, int flags,
+ const xmlChar **namespaces, xmlPatternPtr *patternOut) {
xmlPatternPtr ret = NULL, cur;
xmlPatParserContextPtr ctxt = NULL;
const xmlChar *or, *start;
xmlChar *tmp = NULL;
int type = 0;
int streamable = 1;
+ int error;
- if (pattern == NULL)
- return(NULL);
+ if (patternOut == NULL)
+ return(1);
+
+ if (pattern == NULL) {
+ error = 1;
+ goto error;
+ }
start = pattern;
or = start;
@@ -2296,9 +2298,15 @@ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
}
or++;
}
- if (ctxt == NULL) goto error;
+ if (ctxt == NULL) {
+ error = -1;
+ goto error;
+ }
cur = xmlNewPattern();
- if (cur == NULL) goto error;
+ if (cur == NULL) {
+ error = -1;
+ goto error;
+ }
/*
* Assign string dict.
*/
@@ -2319,8 +2327,10 @@ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
xmlCompileIDCXPathPath(ctxt);
else
xmlCompilePathPattern(ctxt);
- if (ctxt->error != 0)
+ if (ctxt->error != 0) {
+ error = ctxt->error;
goto error;
+ }
xmlFreePatParserContext(ctxt);
ctxt = NULL;
@@ -2336,9 +2346,13 @@ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
streamable = 0;
}
}
- if (streamable)
- xmlStreamCompile(cur);
- if (xmlReversePattern(cur) < 0)
+ if (streamable) {
+ error = xmlStreamCompile(cur);
+ if (error != 0)
+ goto error;
+ }
+ error = xmlReversePattern(cur);
+ if (error != 0)
goto error;
if (tmp != NULL) {
xmlFree(tmp);
@@ -2357,12 +2371,33 @@ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
}
}
- return(ret);
+ *patternOut = ret;
+ return(0);
error:
if (ctxt != NULL) xmlFreePatParserContext(ctxt);
if (ret != NULL) xmlFreePattern(ret);
if (tmp != NULL) xmlFree(tmp);
- return(NULL);
+ *patternOut = NULL;
+ return(error);
+}
+
+/**
+ * xmlPatterncompile:
+ * @pattern: the pattern to compile
+ * @dict: an optional dictionary for interned strings
+ * @flags: compilation flags, see xmlPatternFlags
+ * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
+ *
+ * Compile a pattern.
+ *
+ * Returns the compiled form of the pattern or NULL in case of error
+ */
+xmlPatternPtr
+xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
+ const xmlChar **namespaces) {
+ xmlPatternPtr ret;
+ xmlPatternCompileSafe(pattern, dict, flags, namespaces, &ret);
+ return(ret);
}
/**
diff --git a/relaxng.c b/relaxng.c
index d7c407d..24c3e51 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -53,11 +53,6 @@ static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
#define MAX_ERROR 5
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
typedef struct _xmlRelaxNGSchema xmlRelaxNGSchema;
typedef xmlRelaxNGSchema *xmlRelaxNGSchemaPtr;
@@ -415,7 +410,7 @@ struct _xmlRelaxNGDocument {
* Handle a redefinition of attribute error
*/
static void
-xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *extra)
+xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt)
{
xmlStructuredErrorFunc schannel = NULL;
xmlGenericErrorFunc channel = NULL;
@@ -429,17 +424,8 @@ xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *extra)
data = ctxt->userData;
ctxt->nbErrors++;
}
- if (extra)
- __xmlRaiseError(schannel, channel, data,
- NULL, NULL, XML_FROM_RELAXNGP,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
- else
- __xmlRaiseError(schannel, channel, data,
- NULL, NULL, XML_FROM_RELAXNGP,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
- NULL, NULL, 0, 0, "Memory allocation failed\n");
+
+ xmlRaiseMemoryError(schannel, channel, data, XML_FROM_RELAXNGP, NULL);
}
/**
@@ -450,7 +436,7 @@ xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *extra)
* Handle a redefinition of attribute error
*/
static void
-xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt, const char *extra)
+xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt)
{
xmlStructuredErrorFunc schannel = NULL;
xmlGenericErrorFunc channel = NULL;
@@ -464,17 +450,8 @@ xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt, const char *extra)
data = ctxt->userData;
ctxt->nbErrors++;
}
- if (extra)
- __xmlRaiseError(schannel, channel, data,
- NULL, NULL, XML_FROM_RELAXNGV,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
- NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
- else
- __xmlRaiseError(schannel, channel, data,
- NULL, NULL, XML_FROM_RELAXNGV,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
- NULL, NULL, 0, 0, "Memory allocation failed\n");
+
+ xmlRaiseMemoryError(schannel, channel, data, XML_FROM_RELAXNGV, NULL);
}
/**
@@ -495,6 +472,7 @@ xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
xmlStructuredErrorFunc schannel = NULL;
xmlGenericErrorFunc channel = NULL;
void *data = NULL;
+ int res;
if (ctxt != NULL) {
if (ctxt->serror != NULL)
@@ -504,11 +482,18 @@ xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
data = ctxt->userData;
ctxt->nbErrors++;
}
- __xmlRaiseError(schannel, channel, data,
- NULL, node, XML_FROM_RELAXNGP,
- error, XML_ERR_ERROR, NULL, 0,
- (const char *) str1, (const char *) str2, NULL, 0, 0,
- msg, str1, str2);
+
+ if ((channel == NULL) && (schannel == NULL)) {
+ channel = xmlGenericError;
+ data = xmlGenericErrorContext;
+ }
+
+ res = __xmlRaiseError(schannel, channel, data, NULL, node,
+ XML_FROM_RELAXNGP, error, XML_ERR_ERROR, NULL, 0,
+ (const char *) str1, (const char *) str2, NULL, 0, 0,
+ msg, str1, str2);
+ if (res < 0)
+ xmlRngPErrMemory(ctxt);
}
/**
@@ -529,6 +514,7 @@ xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
xmlStructuredErrorFunc schannel = NULL;
xmlGenericErrorFunc channel = NULL;
void *data = NULL;
+ int res;
if (ctxt != NULL) {
if (ctxt->serror != NULL)
@@ -538,11 +524,18 @@ xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
data = ctxt->userData;
ctxt->nbErrors++;
}
- __xmlRaiseError(schannel, channel, data,
- NULL, node, XML_FROM_RELAXNGV,
- error, XML_ERR_ERROR, NULL, 0,
- (const char *) str1, (const char *) str2, NULL, 0, 0,
- msg, str1, str2);
+
+ if ((channel == NULL) && (schannel == NULL)) {
+ channel = xmlGenericError;
+ data = xmlGenericErrorContext;
+ }
+
+ res = __xmlRaiseError(schannel, channel, data, NULL, node,
+ XML_FROM_RELAXNGV, error, XML_ERR_ERROR, NULL, 0,
+ (const char *) str1, (const char *) str2, NULL, 0, 0,
+ msg, str1, str2);
+ if (res < 0)
+ xmlRngVErrMemory(ctxt);
}
/************************************************************************
@@ -744,7 +737,7 @@ xmlRelaxNGNewRelaxNG(xmlRelaxNGParserCtxtPtr ctxt)
ret = (xmlRelaxNGPtr) xmlMalloc(sizeof(xmlRelaxNG));
if (ret == NULL) {
- xmlRngPErrMemory(ctxt, NULL);
+ xmlRngPErrMemory(ctxt);
return (NULL);
}
memset(ret, 0, sizeof(xmlRelaxNG));
@@ -823,7 +816,7 @@ xmlRelaxNGNewGrammar(xmlRelaxNGParserCtxtPtr ctxt)
ret = (xmlRelaxNGGrammarPtr) xmlMalloc(sizeof(xmlRelaxNGGrammar));
if (ret == NULL) {
- xmlRngPErrMemory(ctxt, NULL);
+ xmlRngPErrMemory(ctxt);
return (NULL);
}
memset(ret, 0, sizeof(xmlRelaxNGGrammar));
@@ -879,7 +872,7 @@ xmlRelaxNGNewDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
ctxt->defTab = (xmlRelaxNGDefinePtr *)
xmlMalloc(ctxt->defMax * sizeof(xmlRelaxNGDefinePtr));
if (ctxt->defTab == NULL) {
- xmlRngPErrMemory(ctxt, "allocating define\n");
+ xmlRngPErrMemory(ctxt);
return (NULL);
}
} else if (ctxt->defMax <= ctxt->defNr) {
@@ -891,14 +884,14 @@ xmlRelaxNGNewDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
sizeof
(xmlRelaxNGDefinePtr));
if (tmp == NULL) {
- xmlRngPErrMemory(ctxt, "allocating define\n");
+ xmlRngPErrMemory(ctxt);
return (NULL);
}
ctxt->defTab = tmp;
}
ret = (xmlRelaxNGDefinePtr) xmlMalloc(sizeof(xmlRelaxNGDefine));
if (ret == NULL) {
- xmlRngPErrMemory(ctxt, "allocating define\n");
+ xmlRngPErrMemory(ctxt);
return (NULL);
}
memset(ret, 0, sizeof(xmlRelaxNGDefine));
@@ -1004,7 +997,7 @@ xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
1) *
sizeof(xmlRelaxNGValidStatePtr));
if (ret == NULL) {
- xmlRngVErrMemory(ctxt, "allocating states\n");
+ xmlRngVErrMemory(ctxt);
return (NULL);
}
ret->nbState = 0;
@@ -1013,7 +1006,7 @@ xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
sizeof
(xmlRelaxNGValidStatePtr));
if (ret->tabState == NULL) {
- xmlRngVErrMemory(ctxt, "allocating states\n");
+ xmlRngVErrMemory(ctxt);
xmlFree(ret);
return (NULL);
}
@@ -1049,7 +1042,7 @@ xmlRelaxNGAddStatesUniq(xmlRelaxNGValidCtxtPtr ctxt,
sizeof
(xmlRelaxNGValidStatePtr));
if (tmp == NULL) {
- xmlRngVErrMemory(ctxt, "adding states\n");
+ xmlRngVErrMemory(ctxt);
return (-1);
}
states->tabState = tmp;
@@ -1089,7 +1082,7 @@ xmlRelaxNGAddStates(xmlRelaxNGValidCtxtPtr ctxt,
sizeof
(xmlRelaxNGValidStatePtr));
if (tmp == NULL) {
- xmlRngVErrMemory(ctxt, "adding states\n");
+ xmlRngVErrMemory(ctxt);
return (-1);
}
states->tabState = tmp;
@@ -1124,7 +1117,7 @@ xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
ctxt->freeStates = (xmlRelaxNGStatesPtr *)
xmlMalloc(ctxt->freeStatesMax * sizeof(xmlRelaxNGStatesPtr));
if (ctxt->freeStates == NULL) {
- xmlRngVErrMemory(ctxt, "storing states\n");
+ xmlRngVErrMemory(ctxt);
}
} else if ((ctxt != NULL)
&& (ctxt->freeStatesNr >= ctxt->freeStatesMax)) {
@@ -1135,7 +1128,7 @@ xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
sizeof
(xmlRelaxNGStatesPtr));
if (tmp == NULL) {
- xmlRngVErrMemory(ctxt, "storing states\n");
+ xmlRngVErrMemory(ctxt);
xmlFree(states->tabState);
xmlFree(states);
return;
@@ -1191,7 +1184,7 @@ xmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node)
(xmlRelaxNGValidStatePtr)
xmlMalloc(sizeof(xmlRelaxNGValidState));
if (ret == NULL) {
- xmlRngVErrMemory(ctxt, "allocating states\n");
+ xmlRngVErrMemory(ctxt);
return (NULL);
}
memset(ret, 0, sizeof(xmlRelaxNGValidState));
@@ -1215,7 +1208,7 @@ xmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node)
ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
sizeof(xmlAttrPtr));
if (ret->attrs == NULL) {
- xmlRngVErrMemory(ctxt, "allocating states\n");
+ xmlRngVErrMemory(ctxt);
return (ret);
}
} else if (ret->maxAttrs < nbAttrs) {
@@ -1224,7 +1217,7 @@ xmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node)
tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, nbAttrs *
sizeof(xmlAttrPtr));
if (tmp == NULL) {
- xmlRngVErrMemory(ctxt, "allocating states\n");
+ xmlRngVErrMemory(ctxt);
return (ret);
}
ret->attrs = tmp;
@@ -1273,7 +1266,7 @@ xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
(xmlRelaxNGValidStatePtr)
xmlMalloc(sizeof(xmlRelaxNGValidState));
if (ret == NULL) {
- xmlRngVErrMemory(ctxt, "allocating states\n");
+ xmlRngVErrMemory(ctxt);
return (NULL);
}
memset(ret, 0, sizeof(xmlRelaxNGValidState));
@@ -1289,7 +1282,7 @@ xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
sizeof(xmlAttrPtr));
if (ret->attrs == NULL) {
- xmlRngVErrMemory(ctxt, "allocating states\n");
+ xmlRngVErrMemory(ctxt);
ret->nbAttrs = 0;
return (ret);
}
@@ -1299,7 +1292,7 @@ xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, state->maxAttrs *
sizeof(xmlAttrPtr));
if (tmp == NULL) {
- xmlRngVErrMemory(ctxt, "allocating states\n");
+ xmlRngVErrMemory(ctxt);
ret->nbAttrs = 0;
return (ret);
}
@@ -1418,6 +1411,42 @@ xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags)
static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
xmlDocPtr doc);
+static xmlDoc *
+xmlRelaxReadFile(xmlRelaxNGParserCtxtPtr ctxt, const char *filename) {
+ xmlParserCtxtPtr pctxt;
+ xmlDocPtr doc;
+
+ pctxt = xmlNewParserCtxt();
+ if (pctxt == NULL) {
+ xmlRngPErrMemory(ctxt);
+ return(NULL);
+ }
+ if (ctxt->serror != NULL)
+ xmlCtxtSetErrorHandler(pctxt, ctxt->serror, ctxt->userData);
+ doc = xmlCtxtReadFile(pctxt, filename, NULL, 0);
+ xmlFreeParserCtxt(pctxt);
+
+ return(doc);
+}
+
+static xmlDoc *
+xmlRelaxReadMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *buf, int size) {
+ xmlParserCtxtPtr pctxt;
+ xmlDocPtr doc;
+
+ pctxt = xmlNewParserCtxt();
+ if (pctxt == NULL) {
+ xmlRngPErrMemory(ctxt);
+ return(NULL);
+ }
+ if (ctxt->serror != NULL)
+ xmlCtxtSetErrorHandler(pctxt, ctxt->serror, ctxt->userData);
+ doc = xmlCtxtReadMemory(pctxt, buf, size, NULL, NULL, 0);
+ xmlFreeParserCtxt(pctxt);
+
+ return(doc);
+}
+
/**
* xmlRelaxNGIncludePush:
* @ctxt: the parser context
@@ -1438,7 +1467,7 @@ xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,
(xmlRelaxNGIncludePtr *) xmlMalloc(ctxt->incMax *
sizeof(ctxt->incTab[0]));
if (ctxt->incTab == NULL) {
- xmlRngPErrMemory(ctxt, "allocating include\n");
+ xmlRngPErrMemory(ctxt);
return (0);
}
}
@@ -1449,7 +1478,7 @@ xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,
ctxt->incMax *
sizeof(ctxt->incTab[0]));
if (ctxt->incTab == NULL) {
- xmlRngPErrMemory(ctxt, "allocating include\n");
+ xmlRngPErrMemory(ctxt);
return (0);
}
}
@@ -1583,7 +1612,7 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
/*
* load the document
*/
- doc = xmlReadFile((const char *) URL,NULL,0);
+ doc = xmlRelaxReadFile(ctxt, (const char *) URL);
if (doc == NULL) {
xmlRngPErr(ctxt, node, XML_RNGP_PARSE_ERROR,
"xmlRelaxNG: could not load %s\n", URL, NULL);
@@ -1595,7 +1624,7 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
*/
ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude));
if (ret == NULL) {
- xmlRngPErrMemory(ctxt, "allocating include\n");
+ xmlRngPErrMemory(ctxt);
xmlFreeDoc(doc);
return (NULL);
}
@@ -1737,7 +1766,7 @@ xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,
sizeof
(xmlRelaxNGValidError));
if (ctxt->errTab == NULL) {
- xmlRngVErrMemory(ctxt, "pushing error\n");
+ xmlRngVErrMemory(ctxt);
return (0);
}
ctxt->err = NULL;
@@ -1750,7 +1779,7 @@ xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,
sizeof
(xmlRelaxNGValidError));
if (ctxt->errTab == NULL) {
- xmlRngVErrMemory(ctxt, "pushing error\n");
+ xmlRngVErrMemory(ctxt);
return (0);
}
ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
@@ -1832,7 +1861,7 @@ xmlRelaxNGDocumentPush(xmlRelaxNGParserCtxtPtr ctxt,
(xmlRelaxNGDocumentPtr *) xmlMalloc(ctxt->docMax *
sizeof(ctxt->docTab[0]));
if (ctxt->docTab == NULL) {
- xmlRngPErrMemory(ctxt, "adding document\n");
+ xmlRngPErrMemory(ctxt);
return (0);
}
}
@@ -1843,7 +1872,7 @@ xmlRelaxNGDocumentPush(xmlRelaxNGParserCtxtPtr ctxt,
ctxt->docMax *
sizeof(ctxt->docTab[0]));
if (ctxt->docTab == NULL) {
- xmlRngPErrMemory(ctxt, "adding document\n");
+ xmlRngPErrMemory(ctxt);
return (0);
}
}
@@ -1913,7 +1942,7 @@ xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
/*
* load the document
*/
- doc = xmlReadFile((const char *) URL,NULL,0);
+ doc = xmlRelaxReadFile(ctxt, (const char *) URL);
if (doc == NULL) {
xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
"xmlRelaxNG: could not load %s\n", URL, NULL);
@@ -1925,8 +1954,7 @@ xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
*/
ret = (xmlRelaxNGDocumentPtr) xmlMalloc(sizeof(xmlRelaxNGDocument));
if (ret == NULL) {
- xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_ERR_NO_MEMORY,
- "xmlRelaxNG: allocate memory for doc %s\n", URL, NULL);
+ xmlRngPErrMemory(ctxt);
xmlFreeDoc(doc);
return (NULL);
}
@@ -2712,17 +2740,13 @@ xmlRelaxNGRegisterTypeLibrary(const xmlChar * namespace, void *data,
if ((xmlRelaxNGRegisteredTypes == NULL) || (namespace == NULL) ||
(check == NULL) || (comp == NULL))
return (-1);
- if (xmlHashLookup(xmlRelaxNGRegisteredTypes, namespace) != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Relax-NG types library '%s' already registered\n",
- namespace);
+ if (xmlHashLookup(xmlRelaxNGRegisteredTypes, namespace) != NULL)
return (-1);
- }
lib =
(xmlRelaxNGTypeLibraryPtr)
xmlMalloc(sizeof(xmlRelaxNGTypeLibrary));
if (lib == NULL) {
- xmlRngVErrMemory(NULL, "adding types library\n");
+ xmlRngVErrMemory(NULL);
return (-1);
}
memset(lib, 0, sizeof(xmlRelaxNGTypeLibrary));
@@ -2735,9 +2759,6 @@ xmlRelaxNGRegisterTypeLibrary(const xmlChar * namespace, void *data,
lib->freef = freef;
ret = xmlHashAddEntry(xmlRelaxNGRegisteredTypes, namespace, lib);
if (ret < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Relax-NG types library failed to register '%s'\n",
- namespace);
xmlRelaxNGFreeTypeLibrary(lib, namespace);
return (-1);
}
@@ -2757,11 +2778,8 @@ xmlRelaxNGInitTypes(void)
if (xmlRelaxNGTypeInitialized != 0)
return (0);
xmlRelaxNGRegisteredTypes = xmlHashCreate(10);
- if (xmlRelaxNGRegisteredTypes == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to allocate sh table for Relax-NG types\n");
+ if (xmlRelaxNGRegisteredTypes == NULL)
return (-1);
- }
xmlRelaxNGRegisterTypeLibrary(BAD_CAST
"http://www.w3.org/2001/XMLSchema-datatypes",
NULL, xmlRelaxNGSchemaTypeHave,
@@ -3723,7 +3741,8 @@ xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
else if (ret == 1)
ret = 0;
} else {
- TODO ret = 0;
+ /* TODO */
+ ret = 0;
}
if (ret == 0)
return (ret);
@@ -3754,7 +3773,8 @@ xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
ret = 1;
}
} else {
- TODO ret = 0;
+ /* TODO */
+ ret = 0;
}
return (ret);
@@ -3911,7 +3931,7 @@ xmlRelaxNGGetElements(xmlRelaxNGParserCtxtPtr ctxt,
ret = (xmlRelaxNGDefinePtr *)
xmlMalloc((max + 1) * sizeof(xmlRelaxNGDefinePtr));
if (ret == NULL) {
- xmlRngPErrMemory(ctxt, "getting element list\n");
+ xmlRngPErrMemory(ctxt);
return (NULL);
}
} else if (max <= len) {
@@ -3921,7 +3941,7 @@ xmlRelaxNGGetElements(xmlRelaxNGParserCtxtPtr ctxt,
temp = xmlRealloc(ret,
(max + 1) * sizeof(xmlRelaxNGDefinePtr));
if (temp == NULL) {
- xmlRngPErrMemory(ctxt, "getting element list\n");
+ xmlRngPErrMemory(ctxt);
xmlFree(ret);
return (NULL);
}
@@ -4019,7 +4039,7 @@ xmlRelaxNGCheckChoiceDeterminism(xmlRelaxNGParserCtxtPtr ctxt,
sizeof(xmlRelaxNGDefinePtr
*));
if (list == NULL) {
- xmlRngPErrMemory(ctxt, "building choice\n");
+ xmlRngPErrMemory(ctxt);
return;
}
i = 0;
@@ -4156,7 +4176,7 @@ xmlRelaxNGCheckGroupAttrs(xmlRelaxNGParserCtxtPtr ctxt,
sizeof(xmlRelaxNGDefinePtr
*));
if (list == NULL) {
- xmlRngPErrMemory(ctxt, "building group\n");
+ xmlRngPErrMemory(ctxt);
return;
}
i = 0;
@@ -4348,7 +4368,7 @@ xmlRelaxNGComputeInterleaves(void *payload, void *data,
return;
error:
- xmlRngPErrMemory(ctxt, "in interleave computation\n");
+ xmlRngPErrMemory(ctxt);
if (groups != NULL) {
for (i = 0; i < nbgroups; i++)
if (groups[i] != NULL) {
@@ -4386,7 +4406,7 @@ xmlRelaxNGParseInterleave(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
if (ctxt->interleaves == NULL)
ctxt->interleaves = xmlHashCreate(10);
if (ctxt->interleaves == NULL) {
- xmlRngPErrMemory(ctxt, "create interleaves\n");
+ xmlRngPErrMemory(ctxt);
} else {
char name[32];
@@ -5253,7 +5273,7 @@ xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
if (tmp != NULL) {
if (last == NULL) {
last = tmp;
- } else {
+ } else if (tmp != ret) {
last->next = tmp;
last = tmp;
}
@@ -6617,13 +6637,11 @@ xmlRelaxNGNewParserCtxt(const char *URL)
ret =
(xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
if (ret == NULL) {
- xmlRngPErrMemory(NULL, "building parser\n");
+ xmlRngPErrMemory(NULL);
return (NULL);
}
memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
ret->URL = xmlStrdup((const xmlChar *) URL);
- ret->error = xmlGenericError;
- ret->userData = xmlGenericErrorContext;
return (ret);
}
@@ -6648,14 +6666,12 @@ xmlRelaxNGNewMemParserCtxt(const char *buffer, int size)
ret =
(xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
if (ret == NULL) {
- xmlRngPErrMemory(NULL, "building parser\n");
+ xmlRngPErrMemory(NULL);
return (NULL);
}
memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
ret->buffer = buffer;
ret->size = size;
- ret->error = xmlGenericError;
- ret->userData = xmlGenericErrorContext;
return (ret);
}
@@ -6684,7 +6700,7 @@ xmlRelaxNGNewDocParserCtxt(xmlDocPtr doc)
ret =
(xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
if (ret == NULL) {
- xmlRngPErrMemory(NULL, "building parser\n");
+ xmlRngPErrMemory(NULL);
xmlFreeDoc(copy);
return (NULL);
}
@@ -7366,7 +7382,7 @@ xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
* First step is to parse the input document into an DOM/Infoset
*/
if (ctxt->URL != NULL) {
- doc = xmlReadFile((const char *) ctxt->URL,NULL,0);
+ doc = xmlRelaxReadFile(ctxt, (const char *) ctxt->URL);
if (doc == NULL) {
xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
"xmlRelaxNGParse: could not load %s\n", ctxt->URL,
@@ -7374,7 +7390,7 @@ xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
return (NULL);
}
} else if (ctxt->buffer != NULL) {
- doc = xmlReadMemory(ctxt->buffer, ctxt->size,NULL,NULL,0);
+ doc = xmlRelaxReadMemory(ctxt, ctxt->buffer, ctxt->size);
if (doc == NULL) {
xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
"xmlRelaxNGParse: could not parse schemas\n", NULL,
@@ -7485,6 +7501,8 @@ xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
* @warn: the warning callback
* @ctx: contextual data for the callbacks
*
+ * DEPRECATED: Use xmlRelaxNGSetParserStructuredErrors.
+ *
* Set the callback functions used to handle errors for a validation context
*/
void
@@ -7679,11 +7697,13 @@ xmlRelaxNGDumpDefine(FILE * output, xmlRelaxNGDefinePtr define)
break;
case XML_RELAXNG_DATATYPE:
case XML_RELAXNG_VALUE:
- TODO break;
+ /* TODO */
+ break;
case XML_RELAXNG_START:
case XML_RELAXNG_EXCEPT:
case XML_RELAXNG_PARAM:
- TODO break;
+ /* TODO */
+ break;
case XML_RELAXNG_NOOP:
xmlRelaxNGDumpDefines(output, define->content);
break;
@@ -7951,7 +7971,7 @@ xmlRelaxNGElemPush(xmlRelaxNGValidCtxtPtr ctxt, xmlRegExecCtxtPtr exec)
sizeof
(xmlRegExecCtxtPtr));
if (ctxt->elemTab == NULL) {
- xmlRngVErrMemory(ctxt, "validating\n");
+ xmlRngVErrMemory(ctxt);
return (-1);
}
}
@@ -7962,7 +7982,7 @@ xmlRelaxNGElemPush(xmlRelaxNGValidCtxtPtr ctxt, xmlRegExecCtxtPtr exec)
sizeof
(xmlRegExecCtxtPtr));
if (ctxt->elemTab == NULL) {
- xmlRngVErrMemory(ctxt, "validating\n");
+ xmlRngVErrMemory(ctxt);
return (-1);
}
}
@@ -8033,13 +8053,7 @@ xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec
ctxt->pstate = -1;
return;
}
- if ((ctxt == NULL) || (define == NULL)) {
- fprintf(stderr, "callback on %s missing info\n", token);
- if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
- ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
- ctxt->pstate = -1;
- return;
- } else if (define->type != XML_RELAXNG_ELEMENT) {
+ if (define->type != XML_RELAXNG_ELEMENT) {
fprintf(stderr, "callback on %s define is not element\n", token);
if (ctxt->errNo == XML_RELAXNG_OK)
ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
@@ -8382,7 +8396,7 @@ xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar * str)
ret = (xmlChar *) xmlMallocAtomic(len + 1);
if (ret == NULL) {
- xmlRngVErrMemory(ctxt, "validating\n");
+ xmlRngVErrMemory(ctxt);
return (NULL);
}
p = ret;
@@ -8793,7 +8807,8 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
}
break;
default:
- TODO ret = -1;
+ /* TODO */
+ ret = -1;
}
return (ret);
}
@@ -8881,7 +8896,9 @@ xmlRelaxNGAttributeMatch(xmlRelaxNGValidCtxtPtr ctxt,
}
return (0);
} else {
- TODO}
+ /* TODO */
+ return (0);
+ }
return (1);
}
@@ -9133,13 +9150,13 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
*/
list = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
if (list == NULL) {
- xmlRngVErrMemory(ctxt, "validating\n");
+ xmlRngVErrMemory(ctxt);
return (-1);
}
memset(list, 0, nbgroups * sizeof(xmlNodePtr));
lasts = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
if (lasts == NULL) {
- xmlRngVErrMemory(ctxt, "validating\n");
+ xmlRngVErrMemory(ctxt);
return (-1);
}
memset(lasts, 0, nbgroups * sizeof(xmlNodePtr));
@@ -9516,7 +9533,8 @@ xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
ctxt->flags = oldflags;
}
} else {
- TODO ret = -1;
+ /* TODO */
+ ret = -1;
}
return (ret);
}
@@ -10226,7 +10244,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
if (content == NULL) {
content = xmlStrdup(BAD_CAST "");
if (content == NULL) {
- xmlRngVErrMemory(ctxt, "validating\n");
+ xmlRngVErrMemory(ctxt);
ret = -1;
break;
}
@@ -10269,7 +10287,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
if (content == NULL) {
content = xmlStrdup(BAD_CAST "");
if (content == NULL) {
- xmlRngVErrMemory(ctxt, "validating\n");
+ xmlRngVErrMemory(ctxt);
ret = -1;
break;
}
@@ -10320,7 +10338,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
if (content == NULL) {
content = xmlStrdup(BAD_CAST "");
if (content == NULL) {
- xmlRngVErrMemory(ctxt, "validating\n");
+ xmlRngVErrMemory(ctxt);
ret = -1;
break;
}
@@ -10344,7 +10362,8 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
}
case XML_RELAXNG_EXCEPT:
case XML_RELAXNG_PARAM:
- TODO ret = -1;
+ /* TODO */
+ ret = -1;
break;
}
ctxt->depth--;
@@ -10371,7 +10390,8 @@ xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
* We should NOT have both ctxt->state and ctxt->states
*/
if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
- TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+ /* TODO */
+ xmlRelaxNGFreeValidState(ctxt, ctxt->state);
ctxt->state = NULL;
}
@@ -10383,7 +10403,8 @@ xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
}
ret = xmlRelaxNGValidateState(ctxt, define);
if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
- TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+ /* TODO */
+ xmlRelaxNGFreeValidState(ctxt, ctxt->state);
ctxt->state = NULL;
}
if ((ctxt->states != NULL) && (ctxt->states->nbState == 1)) {
@@ -10408,7 +10429,8 @@ xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
* We should NOT have both ctxt->state and ctxt->states
*/
if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
- TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+ /* TODO */
+ xmlRelaxNGFreeValidState(ctxt, ctxt->state);
ctxt->state = NULL;
}
if (ret == 0) {
@@ -10474,7 +10496,8 @@ xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
}
}
if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
- TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+ /* TODO */
+ xmlRelaxNGFreeValidState(ctxt, ctxt->state);
ctxt->state = NULL;
}
return (ret);
@@ -10552,9 +10575,16 @@ xmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
memset(&vctxt, 0, sizeof(xmlValidCtxt));
vctxt.valid = 1;
- vctxt.error = ctxt->error;
- vctxt.warning = ctxt->warning;
- vctxt.userData = ctxt->userData;
+
+ if (ctxt->error == NULL) {
+ vctxt.error = xmlGenericError;
+ vctxt.warning = xmlGenericError;
+ vctxt.userData = xmlGenericErrorContext;
+ } else {
+ vctxt.error = ctxt->error;
+ vctxt.warning = ctxt->warning;
+ vctxt.userData = ctxt->userData;
+ }
if (xmlValidateDocumentFinal(&vctxt, doc) != 1)
ret = -1;
@@ -10641,13 +10671,11 @@ xmlRelaxNGNewValidCtxt(xmlRelaxNGPtr schema)
ret = (xmlRelaxNGValidCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGValidCtxt));
if (ret == NULL) {
- xmlRngVErrMemory(NULL, "building context\n");
+ xmlRngVErrMemory(NULL);
return (NULL);
}
memset(ret, 0, sizeof(xmlRelaxNGValidCtxt));
ret->schema = schema;
- ret->error = xmlGenericError;
- ret->userData = xmlGenericErrorContext;
ret->errNr = 0;
ret->errMax = 0;
ret->err = NULL;
@@ -10710,6 +10738,8 @@ xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxtPtr ctxt)
* @warn: the warning function
* @ctx: the functions context
*
+ * DEPRECATED: Use xmlRelaxNGSetValidStructuredErrors.
+ *
* Set the error and warning callback information
*/
void
diff --git a/runsuite.c b/runsuite.c
index 396f3ca..b7f36c2 100644
--- a/runsuite.c
+++ b/runsuite.c
@@ -1036,7 +1036,7 @@ xstcMetadata(const char *metadata, const char *base) {
int
main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
int ret = 0;
- int old_errors, old_tests, old_leaks;
+ int old_errors, old_tests, old_leaks, expected_errors;
logfile = fopen(LOGFILE, "w");
if (logfile == NULL) {
@@ -1054,16 +1054,17 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
old_tests = nb_tests;
old_leaks = nb_leaks;
xsdTest();
+ expected_errors = 3;
printf("Ran %d tests, %d errors, %d leaks\n",
nb_tests - old_tests,
nb_errors - old_errors,
nb_leaks - old_leaks);
- if (nb_errors - old_errors == 10) {
- printf("10 errors were expected\n");
+ if (nb_errors - old_errors == expected_errors) {
+ printf("%d errors were expected\n", expected_errors);
nb_errors = old_errors;
} else {
- printf("10 errors were expected, got %d errors\n",
- nb_errors - old_errors);
+ printf("%d errors were expected, got %d errors\n",
+ expected_errors, nb_errors - old_errors);
nb_errors = old_errors + 1;
}
diff --git a/runtest.c b/runtest.c
index fef5612..4f4a0b8 100644
--- a/runtest.c
+++ b/runtest.c
@@ -11,6 +11,8 @@
* daniel@veillard.com
*/
+#define XML_DEPRECATED
+
#include "libxml.h"
#include
#ifdef HAVE_UNISTD_H
@@ -271,281 +273,9 @@ testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
testErrors[testErrorsSize] = 0;
}
-static void
-channel(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
- va_list args;
- int res;
-
- if (testErrorsSize >= 32768)
- return;
- va_start(args, msg);
- res = vsnprintf(&testErrors[testErrorsSize],
- 32768 - testErrorsSize,
- msg, args);
- va_end(args);
- if (testErrorsSize + res >= 32768) {
- /* buffer is full */
- testErrorsSize = 32768;
- testErrors[testErrorsSize] = 0;
- } else {
- testErrorsSize += res;
- }
- testErrors[testErrorsSize] = 0;
-}
-
-/**
- * xmlParserPrintFileContextInternal:
- * @input: an xmlParserInputPtr input
- *
- * Displays current context within the input content for error tracking
- */
-
-static void
-xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
- xmlGenericErrorFunc chanl, void *data ) {
- const xmlChar *cur, *base, *start;
- unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */
- xmlChar content[81]; /* space for 80 chars + line terminator */
- xmlChar *ctnt;
-
- if ((input == NULL) || (input->cur == NULL))
- return;
-
- cur = input->cur;
- base = input->base;
- /* skip backwards over any end-of-lines */
- while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
- cur--;
- }
- n = 0;
- /* search backwards for beginning-of-line (to max buff size) */
- while ((n++ < (sizeof(content)-1)) && (cur > base) &&
- (*(cur) != '\n') && (*(cur) != '\r'))
- cur--;
- if ((*(cur) == '\n') || (*(cur) == '\r')) {
- cur++;
- } else {
- /* skip over continuation bytes */
- while ((cur < input->cur) && ((*cur & 0xC0) == 0x80))
- cur++;
- }
- /* calculate the error position in terms of the current position */
- col = input->cur - cur;
- /* search forward for end-of-line (to max buff size) */
- n = 0;
- start = cur;
- /* copy selected text to our buffer */
- while ((*cur != 0) && (*(cur) != '\n') && (*(cur) != '\r')) {
- int len = input->end - cur;
- int c = xmlGetUTF8Char(cur, &len);
-
- if ((c < 0) || (n + len > sizeof(content)-1))
- break;
- cur += len;
- n += len;
- }
- memcpy(content, start, n);
- content[n] = 0;
- /* print out the selected text */
- chanl(data ,"%s\n", content);
- /* create blank line with problem pointer */
- n = 0;
- ctnt = content;
- /* (leave buffer space for pointer + line terminator) */
- while ((nfile;
- line = err->line;
- code = err->code;
- domain = err->domain;
- level = err->level;
- node = err->node;
- if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
- (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
- (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
- ctxt = err->ctxt;
- }
- str = err->message;
-
- if (code == XML_ERR_OK)
- return;
-
- if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
- name = node->name;
-
- /*
- * Maintain the compatibility with the legacy error handling
- */
- if (ctxt != NULL) {
- input = ctxt->input;
- if ((input != NULL) && (input->filename == NULL) &&
- (ctxt->inputNr > 1)) {
- cur = input;
- input = ctxt->inputTab[ctxt->inputNr - 2];
- }
- if (input != NULL) {
- if (input->filename)
- channel(data, "%s:%d: ", input->filename, input->line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: ", input->line);
- }
- } else {
- if (file != NULL)
- channel(data, "%s:%d: ", file, line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: ", line);
- }
- /*
- * Skip element name when testing schemas to make memory and streaming
- * output match.
- */
- if ((domain != XML_FROM_SCHEMASV) && (name != NULL)) {
- channel(data, "element %s: ", name);
- }
- if (code == XML_ERR_OK)
- return;
- switch (domain) {
- case XML_FROM_PARSER:
- channel(data, "parser ");
- break;
- case XML_FROM_NAMESPACE:
- channel(data, "namespace ");
- break;
- case XML_FROM_DTD:
- case XML_FROM_VALID:
- channel(data, "validity ");
- break;
- case XML_FROM_HTML:
- channel(data, "HTML parser ");
- break;
- case XML_FROM_MEMORY:
- channel(data, "memory ");
- break;
- case XML_FROM_OUTPUT:
- channel(data, "output ");
- break;
- case XML_FROM_IO:
- channel(data, "I/O ");
- break;
- case XML_FROM_XINCLUDE:
- channel(data, "XInclude ");
- break;
- case XML_FROM_XPATH:
- channel(data, "XPath ");
- break;
- case XML_FROM_XPOINTER:
- channel(data, "parser ");
- break;
- case XML_FROM_REGEXP:
- channel(data, "regexp ");
- break;
- case XML_FROM_MODULE:
- channel(data, "module ");
- break;
- case XML_FROM_SCHEMASV:
- channel(data, "Schemas validity ");
- break;
- case XML_FROM_SCHEMASP:
- channel(data, "Schemas parser ");
- break;
- case XML_FROM_RELAXNGP:
- channel(data, "Relax-NG parser ");
- break;
- case XML_FROM_RELAXNGV:
- channel(data, "Relax-NG validity ");
- break;
- case XML_FROM_CATALOG:
- channel(data, "Catalog ");
- break;
- case XML_FROM_C14N:
- channel(data, "C14N ");
- break;
- case XML_FROM_XSLT:
- channel(data, "XSLT ");
- break;
- default:
- break;
- }
- if (code == XML_ERR_OK)
- return;
- switch (level) {
- case XML_ERR_NONE:
- channel(data, ": ");
- break;
- case XML_ERR_WARNING:
- channel(data, "warning : ");
- break;
- case XML_ERR_ERROR:
- channel(data, "error : ");
- break;
- case XML_ERR_FATAL:
- channel(data, "error : ");
- break;
- }
- if (code == XML_ERR_OK)
- return;
- if (str != NULL) {
- int len;
- len = xmlStrlen((const xmlChar *)str);
- if ((len > 0) && (str[len - 1] != '\n'))
- channel(data, "%s\n", str);
- else
- channel(data, "%s", str);
- } else {
- channel(data, "%s\n", "out of memory error");
- }
- if (code == XML_ERR_OK)
- return;
-
- if (ctxt != NULL) {
- xmlParserPrintFileContextInternal(input, channel, data);
- if (cur != NULL) {
- if (cur->filename)
- channel(data, "%s:%d: \n", cur->filename, cur->line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: \n", cur->line);
- xmlParserPrintFileContextInternal(cur, channel, data);
- }
- }
- if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
- (err->int1 < 100) &&
- (err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
- xmlChar buf[150];
- int i;
-
- channel(data, "%s\n", err->str1);
- for (i=0;i < err->int1;i++)
- buf[i] = ' ';
- buf[i++] = '^';
- buf[i] = 0;
- channel(data, "%s\n", buf);
- }
+ xmlFormatError(err, testErrorHandler, NULL);
}
static void
@@ -561,7 +291,6 @@ initializeLibxml2(void) {
xmlInitParser();
xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
xmlSetExternalEntityLoader(testExternalEntityLoader);
- xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
#ifdef LIBXML_SCHEMAS_ENABLED
xmlSchemaInitTypes();
xmlRelaxNGInitTypes();
@@ -607,10 +336,6 @@ static char *resultFilename(const char *filename, const char *out,
out = "";
strncpy(suffixbuff,suffix,499);
-#ifdef VMS
- if(strstr(base,".") && suffixbuff[0]=='.')
- suffixbuff[0]='_';
-#endif
if (snprintf(res, 499, "%s%s%s", out, base, suffixbuff) >= 499)
res[499] = 0;
@@ -1093,6 +818,16 @@ entityDeclDebug(void *ctx, const xmlChar *name, int type,
xmlEntityPtr ent;
const xmlChar *nullstr = BAD_CAST "(null)";
+ ent = xmlNewEntity(NULL, name, type, publicId, systemId, content);
+ if (systemId != NULL)
+ ent->URI = xmlBuildURI(systemId, (const xmlChar *) ctxt->filename);
+
+ if ((type == XML_INTERNAL_PARAMETER_ENTITY) ||
+ (type == XML_EXTERNAL_PARAMETER_ENTITY))
+ xmlHashAddEntry(ctxt->parameterEntities, name, ent);
+ else
+ xmlHashAddEntry(ctxt->generalEntities, name, ent);
+
/* not all libraries handle printing null pointers nicely */
if (publicId == NULL)
publicId = nullstr;
@@ -1105,16 +840,6 @@ entityDeclDebug(void *ctx, const xmlChar *name, int type,
return;
fprintf(SAXdebug, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
name, type, publicId, systemId, content);
-
- ent = xmlNewEntity(NULL, name, type, publicId, systemId, content);
- if (systemId != NULL)
- ent->URI = xmlBuildURI(systemId, (const xmlChar *) ctxt->filename);
-
- if ((type == XML_INTERNAL_PARAMETER_ENTITY) ||
- (type == XML_EXTERNAL_PARAMETER_ENTITY))
- xmlHashAddEntry(ctxt->parameterEntities, name, ent);
- else
- xmlHashAddEntry(ctxt->generalEntities, name, ent);
}
/**
@@ -1809,10 +1534,6 @@ saxParseTest(const char *filename, const char *result,
return(-1);
}
- /* for SAX we really want the callbacks though the context handlers */
- xmlSetStructuredErrorFunc(NULL, NULL);
- xmlSetGenericErrorFunc(NULL, testErrorHandler);
-
#ifdef LIBXML_HTML_ENABLED
if (options & XML_PARSE_HTML) {
htmlParserCtxtPtr ctxt;
@@ -1832,8 +1553,8 @@ saxParseTest(const char *filename, const char *result,
xmlFreeDoc(ctxt->myDoc);
xmlFreeParserCtxt(ctxt);
}
- if (ret == XML_WAR_UNDECLARED_ENTITY) {
- fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret);
+ if (ret == XML_ERR_UNDECLARED_ENTITY) {
+ fprintf(SAXdebug, "xmlParseDocument returned error %d\n", ret);
ret = 0;
}
if (ret != 0) {
@@ -1873,10 +1594,6 @@ saxParseTest(const char *filename, const char *result,
xmlFreeDoc(ctxt->myDoc);
xmlFreeParserCtxt(ctxt);
}
- if (ret == XML_WAR_UNDECLARED_ENTITY) {
- fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret);
- ret = 0;
- }
fclose(SAXdebug);
if (compareFiles(temp, result)) {
fprintf(stderr, "Got a difference for %s\n", filename);
@@ -1889,10 +1606,6 @@ saxParseTest(const char *filename, const char *result,
free(temp);
}
- /* switch back to structured error handling */
- xmlSetGenericErrorFunc(NULL, NULL);
- xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
-
return(ret);
}
@@ -1926,9 +1639,11 @@ oldParseTest(const char *filename, const char *result,
* base of the test, parse with the old API
*/
#ifdef LIBXML_SAX1_ENABLED
+ xmlGetWarningsDefaultValue = 0;
doc = xmlParseFile(filename);
+ xmlGetWarningsDefaultValue = 1;
#else
- doc = xmlReadFile(filename, NULL, 0);
+ doc = xmlReadFile(filename, NULL, XML_PARSE_NOWARNING);
#endif
if (doc == NULL)
return(1);
@@ -1947,9 +1662,11 @@ oldParseTest(const char *filename, const char *result,
* Parse the saved result to make sure the round trip is okay
*/
#ifdef LIBXML_SAX1_ENABLED
+ xmlGetWarningsDefaultValue = 0;
doc = xmlParseFile(temp);
+ xmlGetWarningsDefaultValue = 1;
#else
- doc = xmlReadFile(temp, NULL, 0);
+ doc = xmlReadFile(temp, NULL, XML_PARSE_NOWARNING);
#endif
if (doc == NULL)
return(1);
@@ -1963,6 +1680,7 @@ oldParseTest(const char *filename, const char *result,
unlink(temp);
free(temp);
}
+
return(res);
}
@@ -2008,6 +1726,7 @@ pushParseTest(const char *filename, const char *result,
else
#endif
ctxt = xmlCreatePushParserCtxt(NULL, NULL, base + cur, chunkSize, filename);
+ xmlCtxtSetErrorHandler(ctxt, testStructuredErrorHandler, NULL);
xmlCtxtUseOptions(ctxt, options);
cur += chunkSize;
chunkSize = 1024;
@@ -2227,6 +1946,7 @@ pushBoundaryTest(const char *filename, const char *result,
else
#endif
ctxt = xmlCreatePushParserCtxt(&bndSAX, NULL, base, 1, filename);
+ xmlCtxtSetErrorHandler(ctxt, testStructuredErrorHandler, NULL);
xmlCtxtUseOptions(ctxt, options);
cur = 1;
consumed = 0;
@@ -2405,7 +2125,7 @@ memParseTest(const char *filename, const char *result,
return(-1);
}
- doc = xmlReadMemory(base, size, filename, NULL, 0);
+ doc = xmlReadMemory(base, size, filename, NULL, XML_PARSE_NOWARNING);
unloadMem(base);
if (doc == NULL) {
return(1);
@@ -2447,7 +2167,8 @@ noentParseTest(const char *filename, const char *result,
/*
* base of the test, parse with the old API
*/
- doc = xmlReadFile(filename, NULL, options);
+ doc = xmlReadFile(filename, NULL,
+ options | XML_PARSE_NOWARNING | XML_PARSE_NOERROR);
if (doc == NULL)
return(1);
temp = resultFilename(filename, temp_directory, ".res");
@@ -2464,7 +2185,8 @@ noentParseTest(const char *filename, const char *result,
/*
* Parse the saved result to make sure the round trip is okay
*/
- doc = xmlReadFile(filename, NULL, options);
+ doc = xmlReadFile(filename, NULL,
+ options | XML_PARSE_NOWARNING | XML_PARSE_NOERROR);
if (doc == NULL)
return(1);
xmlSaveFile(temp, doc);
@@ -2493,6 +2215,7 @@ noentParseTest(const char *filename, const char *result,
static int
errParseTest(const char *filename, const char *result, const char *err,
int options) {
+ xmlParserCtxtPtr ctxt;
xmlDocPtr doc;
const char *base = NULL;
int size, res = 0;
@@ -2500,20 +2223,32 @@ errParseTest(const char *filename, const char *result, const char *err,
nb_tests++;
#ifdef LIBXML_HTML_ENABLED
if (options & XML_PARSE_HTML) {
- doc = htmlReadFile(filename, NULL, options);
+ ctxt = htmlNewParserCtxt();
+ xmlCtxtSetErrorHandler(ctxt, testStructuredErrorHandler, NULL);
+ doc = htmlCtxtReadFile(ctxt, filename, NULL, options);
+ htmlFreeParserCtxt(ctxt);
} else
#endif
+ {
+ ctxt = xmlNewParserCtxt();
+ xmlCtxtSetErrorHandler(ctxt, testStructuredErrorHandler, NULL);
+ doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+ xmlFreeParserCtxt(ctxt);
#ifdef LIBXML_XINCLUDE_ENABLED
- if (options & XML_PARSE_XINCLUDE) {
- doc = xmlReadFile(filename, NULL, options);
- if (xmlXIncludeProcessFlags(doc, options) < 0) {
- xmlFreeDoc(doc);
- doc = NULL;
+ if (options & XML_PARSE_XINCLUDE) {
+ xmlXIncludeCtxtPtr xinc = NULL;
+
+ xinc = xmlXIncludeNewContext(doc);
+ xmlXIncludeSetErrorHandler(xinc, testStructuredErrorHandler, NULL);
+ xmlXIncludeSetFlags(xinc, options);
+ if (xmlXIncludeProcessNode(xinc, (xmlNodePtr) doc) < 0) {
+ testErrorHandler(NULL, "%s : failed to parse\n", filename);
+ xmlFreeDoc(doc);
+ doc = NULL;
+ }
+ xmlXIncludeFreeContext(xinc);
}
- } else
#endif
- {
- doc = xmlReadFile(filename, NULL, options);
}
if (result) {
if (doc == NULL) {
@@ -2566,6 +2301,7 @@ errParseTest(const char *filename, const char *result, const char *err,
static int
fdParseTest(const char *filename, const char *result, const char *err,
int options) {
+ xmlParserCtxtPtr ctxt;
xmlDocPtr doc;
const char *base = NULL;
int size, res = 0, fd;
@@ -2574,11 +2310,17 @@ fdParseTest(const char *filename, const char *result, const char *err,
fd = open(filename, RD_FLAGS);
#ifdef LIBXML_HTML_ENABLED
if (options & XML_PARSE_HTML) {
- doc = htmlReadFd(fd, filename, NULL, options);
+ ctxt = htmlNewParserCtxt();
+ xmlCtxtSetErrorHandler(ctxt, testStructuredErrorHandler, NULL);
+ doc = htmlCtxtReadFd(ctxt, fd, filename, NULL, options);
+ htmlFreeParserCtxt(ctxt);
} else
#endif
{
- doc = xmlReadFd(fd, filename, NULL, options);
+ ctxt = xmlNewParserCtxt();
+ xmlCtxtSetErrorHandler(ctxt, testStructuredErrorHandler, NULL);
+ doc = xmlCtxtReadFd(ctxt, fd, filename, NULL, options);
+ xmlFreeParserCtxt(ctxt);
}
close(fd);
if (result) {
@@ -2750,6 +2492,8 @@ streamParseTest(const char *filename, const char *result, const char *err,
int ret;
reader = xmlReaderForFile(filename, NULL, options);
+ xmlTextReaderSetStructuredErrorHandler(reader, testStructuredErrorHandler,
+ NULL);
ret = streamProcessTest(filename, result, err, reader, NULL, options);
xmlFreeTextReader(reader);
return(ret);
@@ -2772,7 +2516,7 @@ walkerParseTest(const char *filename, const char *result, const char *err,
xmlTextReaderPtr reader;
int ret;
- doc = xmlReadFile(filename, NULL, options);
+ doc = xmlReadFile(filename, NULL, options | XML_PARSE_NOWARNING);
if (doc == NULL) {
fprintf(stderr, "Failed to parse %s\n", filename);
return(-1);
@@ -2810,6 +2554,8 @@ streamMemParseTest(const char *filename, const char *result, const char *err,
return(-1);
}
reader = xmlReaderForMemory(base, size, filename, NULL, options);
+ xmlTextReaderSetStructuredErrorHandler(reader, testStructuredErrorHandler,
+ NULL);
ret = streamProcessTest(filename, result, err, reader, NULL, options);
free((char *)base);
xmlFreeTextReader(reader);
@@ -2828,27 +2574,21 @@ streamMemParseTest(const char *filename, const char *result, const char *err,
static FILE *xpathOutput;
static xmlDocPtr xpathDocument;
-static void
-ignoreGenericError(void *ctx ATTRIBUTE_UNUSED,
- const char *msg ATTRIBUTE_UNUSED, ...) {
-}
-
static void
testXPath(const char *str, int xptr, int expr) {
xmlXPathObjectPtr res;
xmlXPathContextPtr ctxt;
- /* Don't print generic errors to stderr. */
- xmlSetGenericErrorFunc(NULL, ignoreGenericError);
-
nb_tests++;
#if defined(LIBXML_XPTR_ENABLED)
if (xptr) {
ctxt = xmlXPtrNewContext(xpathDocument, NULL, NULL);
+ xmlXPathSetErrorHandler(ctxt, testStructuredErrorHandler, NULL);
res = xmlXPtrEval(BAD_CAST str, ctxt);
} else {
#endif
ctxt = xmlXPathNewContext(xpathDocument);
+ xmlXPathSetErrorHandler(ctxt, testStructuredErrorHandler, NULL);
ctxt->node = xmlDocGetRootElement(xpathDocument);
if (expr)
res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
@@ -2869,9 +2609,6 @@ testXPath(const char *str, int xptr, int expr) {
xmlXPathDebugDumpObject(xpathOutput, res, 0);
xmlXPathFreeObject(res);
xmlXPathFreeContext(ctxt);
-
- /* Reset generic error handler. */
- xmlSetGenericErrorFunc(NULL, NULL);
}
/**
@@ -2906,7 +2643,7 @@ xpathCommonTest(const char *filename, const char *result,
input = fopen(filename, "rb");
if (input == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Cannot open %s for reading\n", filename);
free(temp);
return(-1);
@@ -3081,13 +2818,16 @@ xmlidDocTest(const char *filename,
const char *result,
const char *err,
int options) {
-
+ xmlParserCtxtPtr ctxt;
int res = 0;
int ret = 0;
char *temp;
- xpathDocument = xmlReadFile(filename, NULL,
- options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+ ctxt = xmlNewParserCtxt();
+ xmlCtxtSetErrorHandler(ctxt, testStructuredErrorHandler, NULL);
+ xpathDocument = xmlCtxtReadFile(ctxt, filename, NULL,
+ options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+ xmlFreeParserCtxt(ctxt);
if (xpathDocument == NULL) {
fprintf(stderr, "Failed to load %s\n", filename);
return(-1);
@@ -3506,8 +3246,12 @@ schemasOneTest(const char *sch,
testErrorsSize = parseErrorsSize;
testErrors[parseErrorsSize] = 0;
+ if (schemas == NULL)
+ goto done;
+
ctxt = xmlSchemaNewValidCtxt(schemas);
- xmlSchemaSetValidErrors(ctxt, testErrorHandler, testErrorHandler, ctxt);
+ xmlSchemaSetValidStructuredErrors(ctxt, testStructuredErrorHandler,
+ NULL);
schemasOutput = fopen(temp, "wb");
if (schemasOutput == NULL) {
@@ -3539,19 +3283,23 @@ schemasOneTest(const char *sch,
filename);
}
fclose(schemasOutput);
+
if (result) {
if (compareFiles(temp, result)) {
fprintf(stderr, "Result for %s on %s failed\n", filename, sch);
ret = 1;
}
}
+
+ xmlSchemaFreeValidCtxt(ctxt);
+
+done:
if (compareFileMem(err, testErrors, testErrorsSize)) {
fprintf(stderr, "Error for %s on %s failed\n", filename, sch);
ret = 1;
}
unlink(temp);
- xmlSchemaFreeValidCtxt(ctxt);
}
free(temp);
@@ -3590,7 +3338,7 @@ schemasTest(const char *filename,
/* first compile the schemas if possible */
ctxt = xmlSchemaNewParserCtxt(filename);
- xmlSchemaSetParserErrors(ctxt, testErrorHandler, testErrorHandler, ctxt);
+ xmlSchemaSetParserStructuredErrors(ctxt, testStructuredErrorHandler, NULL);
schemas = xmlSchemaParse(ctxt);
xmlSchemaFreeParserCtxt(ctxt);
parseErrorsSize = testErrorsSize;
@@ -3644,13 +3392,12 @@ schemasTest(const char *filename,
fprintf(stderr, "don't know how to process %s\n", instance);
continue;
}
- if (schemas != NULL) {
- nb_tests++;
- ret = schemasOneTest(filename, instance, result, err,
- options, schemas);
- if (ret != 0)
- res = ret;
- }
+
+ nb_tests++;
+ ret = schemasOneTest(filename, instance, result, err,
+ options, schemas);
+ if (ret != 0)
+ res = ret;
}
globfree(&globbuf);
xmlSchemaFree(schemas);
@@ -3695,7 +3442,7 @@ rngOneTest(const char *sch,
}
ctxt = xmlRelaxNGNewValidCtxt(schemas);
- xmlRelaxNGSetValidErrors(ctxt, testErrorHandler, testErrorHandler, ctxt);
+ xmlRelaxNGSetValidStructuredErrors(ctxt, testStructuredErrorHandler, NULL);
ret = xmlRelaxNGValidateDoc(ctxt, doc);
if (ret == 0) {
testErrorHandler(NULL, "%s validates\n", filename);
@@ -3754,7 +3501,8 @@ rngTest(const char *filename,
/* first compile the schemas if possible */
ctxt = xmlRelaxNGNewParserCtxt(filename);
- xmlRelaxNGSetParserErrors(ctxt, testErrorHandler, testErrorHandler, ctxt);
+ xmlRelaxNGSetParserStructuredErrors(ctxt, testStructuredErrorHandler,
+ NULL);
schemas = xmlRelaxNGParse(ctxt);
xmlRelaxNGFreeParserCtxt(ctxt);
if (schemas == NULL)
@@ -3808,7 +3556,7 @@ rngTest(const char *filename,
if (compareFileMem(err, testErrors, testErrorsSize)) {
fprintf(stderr, "Error for %s on %s failed\n", instance,
filename);
- res = 1;
+ ret = 1;
}
}
globfree(&globbuf);
@@ -3894,6 +3642,8 @@ rngStreamTest(const char *filename,
continue;
}
reader = xmlReaderForFile(instance, NULL, options);
+ xmlTextReaderSetStructuredErrorHandler(reader,
+ testStructuredErrorHandler, NULL);
if (reader == NULL) {
fprintf(stderr, "Failed to build reader for %s\n", instance);
}
@@ -4293,7 +4043,8 @@ c14nRunTest(const char* xml_filename, int with_comments, int mode,
* build an XML tree from a the file; we need to add default
* attributes and resolve all character and entities references
*/
- doc = xmlReadFile(xml_filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+ doc = xmlReadFile(xml_filename, NULL,
+ XML_PARSE_DTDATTR | XML_PARSE_NOENT | XML_PARSE_NOWARNING);
if (doc == NULL) {
fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename);
return(-1);
@@ -4657,13 +4408,19 @@ regexpTest(const char *filename, const char *result, const char *err,
char expression[5000];
int len, ret, res = 0;
+ /*
+ * TODO: Custom error handler for regexp
+ */
+ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
+
nb_tests++;
input = fopen(filename, "rb");
if (input == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Cannot open %s for reading\n", filename);
- return(-1);
+ ret = -1;
+ goto done;
}
temp = resultFilename(filename, "", ".res");
if (temp == NULL) {
@@ -4674,7 +4431,8 @@ regexpTest(const char *filename, const char *result, const char *err,
if (output == NULL) {
fprintf(stderr, "failed to open output file %s\n", temp);
free(temp);
- return(-1);
+ ret = -1;
+ goto done;
}
while (fgets(expression, 4500, input) != NULL) {
len = strlen(expression);
@@ -4732,6 +4490,9 @@ regexpTest(const char *filename, const char *result, const char *err,
res = 1;
}
+done:
+ xmlSetStructuredErrorFunc(NULL, NULL);
+
return(res);
}
@@ -4779,7 +4540,7 @@ automataTest(const char *filename, const char *result,
input = fopen(filename, "rb");
if (input == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Cannot open %s for reading\n", filename);
return(-1);
}
@@ -4797,14 +4558,14 @@ automataTest(const char *filename, const char *result,
am = xmlNewAutomata();
if (am == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Cannot create automata\n");
fclose(input);
return(-1);
}
states[0] = xmlAutomataGetInitState(am);
if (states[0] == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Cannot get start state\n");
xmlFreeAutomata(am);
fclose(input);
@@ -4828,7 +4589,7 @@ automataTest(const char *filename, const char *result,
from = scanNumber(&ptr);
if (*ptr != ' ') {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Bad line %s\n", expr);
break;
}
@@ -4837,7 +4598,7 @@ automataTest(const char *filename, const char *result,
ptr++;
to = scanNumber(&ptr);
if (*ptr != ' ') {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Bad line %s\n", expr);
break;
}
@@ -4852,7 +4613,7 @@ automataTest(const char *filename, const char *result,
from = scanNumber(&ptr);
if (*ptr != ' ') {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Bad line %s\n", expr);
break;
}
@@ -4869,7 +4630,7 @@ automataTest(const char *filename, const char *result,
state = scanNumber(&ptr);
if (states[state] == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Bad state %d : %s\n", state, expr);
break;
}
@@ -4881,7 +4642,7 @@ automataTest(const char *filename, const char *result,
from = scanNumber(&ptr);
if (*ptr != ' ') {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Bad line %s\n", expr);
break;
}
@@ -4890,7 +4651,7 @@ automataTest(const char *filename, const char *result,
ptr++;
to = scanNumber(&ptr);
if (*ptr != ' ') {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Bad line %s\n", expr);
break;
}
@@ -4899,14 +4660,14 @@ automataTest(const char *filename, const char *result,
ptr++;
min = scanNumber(&ptr);
if (*ptr != ' ') {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Bad line %s\n", expr);
break;
}
ptr++;
max = scanNumber(&ptr);
if (*ptr != ' ') {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Bad line %s\n", expr);
break;
}
@@ -4919,7 +4680,7 @@ automataTest(const char *filename, const char *result,
xmlFreeAutomata(am);
am = NULL;
if (regexp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Failed to compile the automata");
break;
}
@@ -4947,7 +4708,7 @@ automataTest(const char *filename, const char *result,
exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
ret = xmlRegExecPushString(exec, BAD_CAST expr, NULL);
} else {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(stderr,
"Unexpected line %s\n", expr);
}
}
@@ -5209,10 +4970,29 @@ launchTests(testDescPtr tst) {
char *result;
char *error;
int mem;
- xmlCharEncodingHandlerPtr ebcdicHandler, eucJpHandler;
+ xmlCharEncodingHandlerPtr ebcdicHandler, ibm1141Handler, eucJpHandler;
ebcdicHandler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC);
+ ibm1141Handler = xmlFindCharEncodingHandler("IBM-1141");
+
+ /*
+ * When decoding EUC-JP, musl doesn't seem to support 0x8F control
+ * codes.
+ */
eucJpHandler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EUC_JP);
+ if (eucJpHandler != NULL) {
+ xmlBufferPtr in, out;
+
+ in = xmlBufferCreateSize(10);
+ xmlBufferCCat(in, "\x8f\xe9\xae");
+ out = xmlBufferCreateSize(10);
+ if (xmlCharEncInFunc(eucJpHandler, out, in) != 3) {
+ xmlCharEncCloseFunc(eucJpHandler);
+ eucJpHandler = NULL;
+ }
+ xmlBufferFree(out);
+ xmlBufferFree(in);
+ }
if (tst == NULL) return(-1);
if (tst->in != NULL) {
@@ -5223,7 +5003,7 @@ launchTests(testDescPtr tst) {
for (i = 0;i < globbuf.gl_pathc;i++) {
if (!checkTestFile(globbuf.gl_pathv[i]))
continue;
- if (((ebcdicHandler == NULL) &&
+ if ((((ebcdicHandler == NULL) || (ibm1141Handler == NULL)) &&
(strstr(globbuf.gl_pathv[i], "ebcdic") != NULL)) ||
((eucJpHandler == NULL) &&
(strstr(globbuf.gl_pathv[i], "icu_parse_test") != NULL)))
@@ -5289,6 +5069,7 @@ launchTests(testDescPtr tst) {
}
xmlCharEncCloseFunc(ebcdicHandler);
+ xmlCharEncCloseFunc(ibm1141Handler);
xmlCharEncCloseFunc(eucJpHandler);
return(err);
diff --git a/runxmlconf.c b/runxmlconf.c
index 8505590..36ab448 100644
--- a/runxmlconf.c
+++ b/runxmlconf.c
@@ -173,7 +173,6 @@ initializeLibxml2(void) {
*/
if (ctxtXPath->cache != NULL)
xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
- xmlSetStructuredErrorFunc(NULL, testErrorHandler);
}
/************************************************************************
@@ -194,6 +193,7 @@ xmlconfTestInvalid(const char *id, const char *filename, int options) {
id, filename);
return(0);
}
+ xmlCtxtSetErrorHandler(ctxt, testErrorHandler, NULL);
doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
if (doc == NULL) {
test_log("test %s : %s invalid document turned not well-formed too\n",
@@ -224,6 +224,7 @@ xmlconfTestValid(const char *id, const char *filename, int options) {
id, filename);
return(0);
}
+ xmlCtxtSetErrorHandler(ctxt, testErrorHandler, NULL);
doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
if (doc == NULL) {
test_log("test %s : %s failed to parse a valid document\n",
@@ -246,14 +247,17 @@ xmlconfTestValid(const char *id, const char *filename, int options) {
static int
xmlconfTestNotNSWF(const char *id, const char *filename, int options) {
+ xmlParserCtxtPtr ctxt;
xmlDocPtr doc;
int ret = 1;
+ ctxt = xmlNewParserCtxt();
+ xmlCtxtSetErrorHandler(ctxt, testErrorHandler, NULL);
/*
* In case of Namespace errors, libxml2 will still parse the document
* but log a Namespace error.
*/
- doc = xmlReadFile(filename, NULL, options);
+ doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
if (doc == NULL) {
test_log("test %s : %s failed to parse the XML\n",
id, filename);
@@ -271,15 +275,19 @@ xmlconfTestNotNSWF(const char *id, const char *filename, int options) {
}
xmlFreeDoc(doc);
}
+ xmlFreeParserCtxt(ctxt);
return(ret);
}
static int
xmlconfTestNotWF(const char *id, const char *filename, int options) {
+ xmlParserCtxtPtr ctxt;
xmlDocPtr doc;
int ret = 1;
- doc = xmlReadFile(filename, NULL, options);
+ ctxt = xmlNewParserCtxt();
+ xmlCtxtSetErrorHandler(ctxt, testErrorHandler, NULL);
+ doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
if (doc != NULL) {
test_log("test %s : %s failed to detect not well formedness\n",
id, filename);
@@ -287,6 +295,7 @@ xmlconfTestNotWF(const char *id, const char *filename, int options) {
xmlFreeDoc(doc);
ret = 0;
}
+ xmlFreeParserCtxt(ctxt);
return(ret);
}
@@ -416,7 +425,6 @@ xmlconfTestItem(xmlDocPtr doc, xmlNodePtr cur) {
test_log("test %s : %s leaked %d bytes\n",
id, filename, final - mem);
nb_leaks++;
- xmlMemDisplayLast(logfile, final - mem);
}
nb_tests++;
diff --git a/schematron.c b/schematron.c
index a825920..1de25de 100644
--- a/schematron.c
+++ b/schematron.c
@@ -63,16 +63,6 @@ static const xmlChar *xmlOldSchematronNs = SCT_OLD_NS;
node = node->next; \
}
-/**
- * TODO:
- *
- * macro to flag unimplemented blocks
- */
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
typedef enum {
XML_SCHEMATRON_ASSERT=1,
XML_SCHEMATRON_REPORT=2
@@ -242,13 +232,11 @@ struct _xmlSchematronParserCtxt {
* Handle an out of memory condition
*/
static void
-xmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt,
- const char *extra, xmlNodePtr node)
+xmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt)
{
if (ctxt != NULL)
ctxt->nberrors++;
- __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
- extra);
+ xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_SCHEMASP, NULL);
}
/**
@@ -269,6 +257,7 @@ xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error,
xmlGenericErrorFunc channel = NULL;
xmlStructuredErrorFunc schannel = NULL;
void *data = NULL;
+ int res;
if (ctxt != NULL) {
ctxt->nberrors++;
@@ -276,10 +265,18 @@ xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error,
data = ctxt->userData;
schannel = ctxt->serror;
}
- __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
- error, XML_ERR_ERROR, NULL, 0,
- (const char *) str1, (const char *) str2, NULL, 0, 0,
- msg, str1, str2);
+
+ if ((channel == NULL) && (schannel == NULL)) {
+ channel = xmlGenericError;
+ data = xmlGenericErrorContext;
+ }
+
+ res = __xmlRaiseError(schannel, channel, data, ctxt, node,
+ XML_FROM_SCHEMASP, error, XML_ERR_ERROR, NULL, 0,
+ (const char *) str1, (const char *) str2, NULL, 0, 0,
+ msg, str1, str2);
+ if (res < 0)
+ xmlSchematronPErrMemory(ctxt);
}
/**
@@ -290,15 +287,53 @@ xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error,
* Handle an out of memory condition
*/
static void
-xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt,
- const char *extra, xmlNodePtr node)
+xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt)
{
if (ctxt != NULL) {
ctxt->nberrors++;
ctxt->err = XML_SCHEMAV_INTERNAL;
}
- __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
- extra);
+ xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_SCHEMASV, NULL);
+}
+
+/**
+ * xmlSchematronVErr:
+ * @ctxt: the parsing context
+ * @node: the context node
+ * @error: the error code
+ * @msg: the error message
+ * @str1: extra data
+ * @str2: extra data
+ *
+ * Handle a validation error
+ */
+static void LIBXML_ATTR_FORMAT(3,0)
+xmlSchematronVErr(xmlSchematronValidCtxtPtr ctxt, int error,
+ const char *msg, const xmlChar * str1)
+{
+ xmlGenericErrorFunc channel = NULL;
+ xmlStructuredErrorFunc schannel = NULL;
+ void *data = NULL;
+ int res;
+
+ if (ctxt != NULL) {
+ ctxt->nberrors++;
+ channel = ctxt->error;
+ data = ctxt->userData;
+ schannel = ctxt->serror;
+ }
+
+ if ((channel == NULL) && (schannel == NULL)) {
+ channel = xmlGenericError;
+ data = xmlGenericErrorContext;
+ }
+
+ res = __xmlRaiseError(schannel, channel, data, ctxt, NULL,
+ XML_FROM_SCHEMASV, error, XML_ERR_ERROR, NULL, 0,
+ (const char *) str1, NULL, NULL, 0, 0,
+ msg, str1);
+ if (res < 0)
+ xmlSchematronVErrMemory(ctxt);
}
/************************************************************************
@@ -347,7 +382,7 @@ xmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt,
ret = (xmlSchematronTestPtr) xmlMalloc(sizeof(xmlSchematronTest));
if (ret == NULL) {
- xmlSchematronPErrMemory(ctxt, "allocating schema test", node);
+ xmlSchematronPErrMemory(ctxt);
return (NULL);
}
memset(ret, 0, sizeof(xmlSchematronTest));
@@ -451,7 +486,7 @@ xmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema,
ret = (xmlSchematronRulePtr) xmlMalloc(sizeof(xmlSchematronRule));
if (ret == NULL) {
- xmlSchematronPErrMemory(ctxt, "allocating schema rule", node);
+ xmlSchematronPErrMemory(ctxt);
return (NULL);
}
memset(ret, 0, sizeof(xmlSchematronRule));
@@ -532,7 +567,7 @@ xmlSchematronAddPattern(xmlSchematronParserCtxtPtr ctxt,
ret = (xmlSchematronPatternPtr) xmlMalloc(sizeof(xmlSchematronPattern));
if (ret == NULL) {
- xmlSchematronPErrMemory(ctxt, "allocating schema pattern", node);
+ xmlSchematronPErrMemory(ctxt);
return (NULL);
}
memset(ret, 0, sizeof(xmlSchematronPattern));
@@ -584,7 +619,7 @@ xmlSchematronNewSchematron(xmlSchematronParserCtxtPtr ctxt)
ret = (xmlSchematronPtr) xmlMalloc(sizeof(xmlSchematron));
if (ret == NULL) {
- xmlSchematronPErrMemory(ctxt, "allocating schema", NULL);
+ xmlSchematronPErrMemory(ctxt);
return (NULL);
}
memset(ret, 0, sizeof(xmlSchematron));
@@ -639,8 +674,7 @@ xmlSchematronNewParserCtxt(const char *URL)
(xmlSchematronParserCtxtPtr)
xmlMalloc(sizeof(xmlSchematronParserCtxt));
if (ret == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating schema parser context",
- NULL);
+ xmlSchematronPErrMemory(NULL);
return (NULL);
}
memset(ret, 0, sizeof(xmlSchematronParserCtxt));
@@ -650,8 +684,7 @@ xmlSchematronNewParserCtxt(const char *URL)
ret->includes = NULL;
ret->xctxt = xmlXPathNewContext(NULL);
if (ret->xctxt == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
- NULL);
+ xmlSchematronPErrMemory(NULL);
xmlSchematronFreeParserCtxt(ret);
return (NULL);
}
@@ -681,8 +714,7 @@ xmlSchematronNewMemParserCtxt(const char *buffer, int size)
(xmlSchematronParserCtxtPtr)
xmlMalloc(sizeof(xmlSchematronParserCtxt));
if (ret == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating schema parser context",
- NULL);
+ xmlSchematronPErrMemory(NULL);
return (NULL);
}
memset(ret, 0, sizeof(xmlSchematronParserCtxt));
@@ -691,8 +723,7 @@ xmlSchematronNewMemParserCtxt(const char *buffer, int size)
ret->dict = xmlDictCreate();
ret->xctxt = xmlXPathNewContext(NULL);
if (ret->xctxt == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
- NULL);
+ xmlSchematronPErrMemory(NULL);
xmlSchematronFreeParserCtxt(ret);
return (NULL);
}
@@ -720,8 +751,7 @@ xmlSchematronNewDocParserCtxt(xmlDocPtr doc)
(xmlSchematronParserCtxtPtr)
xmlMalloc(sizeof(xmlSchematronParserCtxt));
if (ret == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating schema parser context",
- NULL);
+ xmlSchematronPErrMemory(NULL);
return (NULL);
}
memset(ret, 0, sizeof(xmlSchematronParserCtxt));
@@ -731,8 +761,7 @@ xmlSchematronNewDocParserCtxt(xmlDocPtr doc)
ret->preserve = 1;
ret->xctxt = xmlXPathNewContext(doc);
if (ret->xctxt == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
- NULL);
+ xmlSchematronPErrMemory(NULL);
xmlSchematronFreeParserCtxt(ret);
return (NULL);
}
@@ -780,8 +809,7 @@ xmlSchematronPushInclude(xmlSchematronParserCtxtPtr ctxt,
ctxt->includes = (xmlNodePtr *)
xmlMalloc(ctxt->maxIncludes * 2 * sizeof(xmlNodePtr));
if (ctxt->includes == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating parser includes",
- NULL);
+ xmlSchematronPErrMemory(NULL);
return;
}
ctxt->nbIncludes = 0;
@@ -792,8 +820,7 @@ xmlSchematronPushInclude(xmlSchematronParserCtxtPtr ctxt,
xmlRealloc(ctxt->includes, ctxt->maxIncludes * 4 *
sizeof(xmlNodePtr));
if (tmp == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating parser includes",
- NULL);
+ xmlSchematronPErrMemory(NULL);
return;
}
ctxt->includes = tmp;
@@ -850,8 +877,7 @@ xmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt,
ctxt->namespaces = (const xmlChar **)
xmlMalloc(ctxt->maxNamespaces * 2 * sizeof(const xmlChar *));
if (ctxt->namespaces == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
- NULL);
+ xmlSchematronPErrMemory(NULL);
return;
}
ctxt->nbNamespaces = 0;
@@ -862,8 +888,7 @@ xmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt,
xmlRealloc((xmlChar **) ctxt->namespaces, ctxt->maxNamespaces * 4 *
sizeof(const xmlChar *));
if (tmp == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
- NULL);
+ xmlSchematronPErrMemory(NULL);
return;
}
ctxt->namespaces = tmp;
@@ -1493,9 +1518,6 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
ret = xmlStrcat(ret, spacer);
ret = xmlStrcat(ret, eval->nodesetval->nodeTab[indx]->name);
}
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Empty node set\n");
}
break;
}
@@ -1521,8 +1543,8 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
ret = xmlStrcat(ret, eval->stringval);
break;
default:
- xmlGenericError(xmlGenericErrorContext,
- "Unsupported XPATH Type: %d\n", eval->type);
+ xmlSchematronVErr(ctxt, XML_ERR_INTERNAL_ERROR,
+ "Unsupported XPATH Type\n", NULL);
}
xmlXPathFreeObject(eval);
xmlXPathFreeCompExpr(comp);
@@ -1581,7 +1603,7 @@ xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt,
(test->type == XML_SCHEMATRON_REPORT))
return;
if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
- TODO
+ /* TODO */
} else {
xmlChar *path;
char msg[1000];
@@ -1612,26 +1634,33 @@ xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt,
line, (const char *) report);
if (ctxt->flags & XML_SCHEMATRON_OUT_ERROR) {
- xmlStructuredErrorFunc schannel = NULL;
- xmlGenericErrorFunc channel = NULL;
- void *data = NULL;
-
- if (ctxt != NULL) {
- if (ctxt->serror != NULL)
- schannel = ctxt->serror;
- else
- channel = ctxt->error;
- data = ctxt->userData;
+ xmlStructuredErrorFunc schannel;
+ xmlGenericErrorFunc channel;
+ void *data;
+ int res;
+
+ schannel = ctxt->serror;
+ channel = ctxt->error;
+ data = ctxt->userData;
+
+ if ((channel == NULL) && (schannel == NULL)) {
+ channel = xmlGenericError;
+ data = xmlGenericErrorContext;
}
- __xmlRaiseError(schannel, channel, data,
- NULL, cur, XML_FROM_SCHEMATRONV,
- (test->type == XML_SCHEMATRON_ASSERT)?XML_SCHEMATRONV_ASSERT:XML_SCHEMATRONV_REPORT,
- XML_ERR_ERROR, NULL, line,
- (pattern == NULL)?NULL:((const char *) pattern->name),
- (const char *) path,
- (const char *) report, 0, 0,
- "%s", msg);
+ res = __xmlRaiseError(schannel, channel, data, NULL, cur,
+ XML_FROM_SCHEMATRONV,
+ (test->type == XML_SCHEMATRON_ASSERT) ?
+ XML_SCHEMATRONV_ASSERT :
+ XML_SCHEMATRONV_REPORT,
+ XML_ERR_ERROR, NULL, line,
+ (pattern == NULL) ?
+ NULL :
+ (const char *) pattern->name,
+ (const char *) path, (const char *) report, 0, 0,
+ "%s", msg);
+ if (res < 0)
+ xmlSchematronVErrMemory(ctxt);
} else {
xmlSchematronReportOutput(ctxt, cur, &msg[0]);
}
@@ -1658,7 +1687,7 @@ xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt,
if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) || (ctxt->flags & XML_SCHEMATRON_OUT_ERROR)) /* Error gives pattern name as part of error */
return;
if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
- TODO
+ /* TODO */
} else {
char msg[1000];
@@ -1713,8 +1742,7 @@ xmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options)
ret = (xmlSchematronValidCtxtPtr) xmlMalloc(sizeof(xmlSchematronValidCtxt));
if (ret == NULL) {
- xmlSchematronVErrMemory(NULL, "allocating validation context",
- NULL);
+ xmlSchematronVErrMemory(NULL);
return (NULL);
}
memset(ret, 0, sizeof(xmlSchematronValidCtxt));
@@ -1723,8 +1751,7 @@ xmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options)
ret->xctxt = xmlXPathNewContext(NULL);
ret->flags = options;
if (ret->xctxt == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
- NULL);
+ xmlSchematronPErrMemory(NULL);
xmlSchematronFreeValidCtxt(ret);
return (NULL);
}
@@ -1870,7 +1897,9 @@ xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt,
* Returns -1 in case of errors, otherwise 0
*/
static int
-xmlSchematronRegisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let,
+xmlSchematronRegisterVariables(xmlSchematronValidCtxtPtr vctxt,
+ xmlXPathContextPtr ctxt,
+ xmlSchematronLetPtr let,
xmlDocPtr instance, xmlNodePtr cur)
{
xmlXPathObjectPtr let_eval;
@@ -1880,13 +1909,14 @@ xmlSchematronRegisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let,
while (let != NULL) {
let_eval = xmlXPathCompiledEval(let->comp, ctxt);
if (let_eval == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Evaluation of compiled expression failed\n");
+ xmlSchematronVErr(vctxt, XML_ERR_INTERNAL_ERROR,
+ "Evaluation of compiled expression failed\n",
+ NULL);
return -1;
}
if(xmlXPathRegisterVariableNS(ctxt, let->name, NULL, let_eval)) {
- xmlGenericError(xmlGenericErrorContext,
- "Registering a let variable failed\n");
+ xmlSchematronVErr(vctxt, XML_ERR_INTERNAL_ERROR,
+ "Registering a let variable failed\n", NULL);
return -1;
}
let = let->next;
@@ -1904,12 +1934,14 @@ xmlSchematronRegisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let,
* Returns -1 in case of errors, otherwise 0
*/
static int
-xmlSchematronUnregisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let)
+xmlSchematronUnregisterVariables(xmlSchematronValidCtxtPtr vctxt,
+ xmlXPathContextPtr ctxt,
+ xmlSchematronLetPtr let)
{
while (let != NULL) {
if (xmlXPathRegisterVariableNS(ctxt, let->name, NULL, NULL)) {
- xmlGenericError(xmlGenericErrorContext,
- "Unregistering a let variable failed\n");
+ xmlSchematronVErr(vctxt, XML_ERR_INTERNAL_ERROR,
+ "Unregistering a let variable failed\n", NULL);
return -1;
}
let = let->next;
@@ -1941,7 +1973,7 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance)
ctxt->nberrors = 0;
root = xmlDocGetRootElement(instance);
if (root == NULL) {
- TODO
+ /* TODO */
ctxt->nberrors++;
return(1);
}
@@ -1958,7 +1990,8 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance)
if (xmlPatternMatch(rule->pattern, cur) == 1) {
test = rule->tests;
- if (xmlSchematronRegisterVariables(ctxt->xctxt, rule->lets, instance, cur))
+ if (xmlSchematronRegisterVariables(ctxt, ctxt->xctxt,
+ rule->lets, instance, cur))
return -1;
while (test != NULL) {
@@ -1966,7 +1999,8 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance)
test = test->next;
}
- if (xmlSchematronUnregisterVariables(ctxt->xctxt, rule->lets))
+ if (xmlSchematronUnregisterVariables(ctxt, ctxt->xctxt,
+ rule->lets))
return -1;
}
@@ -1996,15 +2030,16 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance)
while (rule != NULL) {
if (xmlPatternMatch(rule->pattern, cur) == 1) {
test = rule->tests;
- xmlSchematronRegisterVariables(ctxt->xctxt, rule->lets,
- instance, cur);
+ xmlSchematronRegisterVariables(ctxt, ctxt->xctxt,
+ rule->lets, instance, cur);
while (test != NULL) {
xmlSchematronRunTest(ctxt, test, instance, cur, pattern);
test = test->next;
}
- xmlSchematronUnregisterVariables(ctxt->xctxt, rule->lets);
+ xmlSchematronUnregisterVariables(ctxt, ctxt->xctxt,
+ rule->lets);
}
rule = rule->patnext;
}
diff --git a/testapi.c b/testapi.c
index 0a0aadf..d85e560 100644
--- a/testapi.c
+++ b/testapi.c
@@ -207,12 +207,6 @@ int main(int argc, char **argv) {
#include
#include
-/*
- We manually define xmlErrMemory because it's normal declaration
- is "hidden" by #ifdef IN_LIBXML
-*/
-void xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra);
-
/*
We need some "remote" addresses, but want to avoid getting into
name resolution delays, so we use these
@@ -229,17 +223,6 @@ static void *gen_void_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
static void des_void_ptr(int no ATTRIBUTE_UNUSED, void *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
}
-#if 0
-#define gen_nb_const_void_ptr 2
-
-static const void *gen_const_void_ptr(int no, int nr ATTRIBUTE_UNUSED) {
- if (no == 0) return((const void *) "immutable string");
- return(NULL);
-}
-static void des_const_void_ptr(int no ATTRIBUTE_UNUSED, const void *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
-}
-#endif
-
#define gen_nb_userdata 3
static void *gen_userdata(int no, int nr ATTRIBUTE_UNUSED) {
@@ -372,7 +355,7 @@ static void des_int_ptr(int no ATTRIBUTE_UNUSED, int *val ATTRIBUTE_UNUSED, int
#define gen_nb_const_char_ptr 4
-static char *gen_const_char_ptr(int no, int nr ATTRIBUTE_UNUSED) {
+static const char *gen_const_char_ptr(int no, int nr ATTRIBUTE_UNUSED) {
if (no == 0) return((char *) "foo");
if (no == 1) return((char *) "");
if (no == 2) return((char *) "test/ent2");
@@ -412,7 +395,7 @@ static void des_debug_FILE_ptr(int no ATTRIBUTE_UNUSED, FILE *val, int nr ATTRIB
#define gen_nb_const_xmlChar_ptr 5
-static xmlChar *gen_const_xmlChar_ptr(int no, int nr ATTRIBUTE_UNUSED) {
+static const xmlChar *gen_const_xmlChar_ptr(int no, int nr ATTRIBUTE_UNUSED) {
if (no == 0) return((xmlChar *) "foo");
if (no == 1) return((xmlChar *) "");
if (no == 2) return((xmlChar *) "n" "\xf8" "ne");
@@ -885,7 +868,8 @@ static void desret_xmlNanoHTTPCtxtPtr(void *val) {
#endif
/* cut and pasted from autogenerated to avoid troubles */
#define gen_nb_const_xmlChar_ptr_ptr 1
-static xmlChar ** gen_const_xmlChar_ptr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+static const xmlChar **
+gen_const_xmlChar_ptr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
return(NULL);
}
static void des_const_xmlChar_ptr_ptr(int no ATTRIBUTE_UNUSED, const xmlChar ** val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
@@ -899,21 +883,13 @@ static void des_unsigned_char_ptr(int no ATTRIBUTE_UNUSED, unsigned char * val A
}
#define gen_nb_const_unsigned_char_ptr 1
-static unsigned char * gen_const_unsigned_char_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+static const unsigned char *
+gen_const_unsigned_char_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
return(NULL);
}
static void des_const_unsigned_char_ptr(int no ATTRIBUTE_UNUSED, const unsigned char * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
}
-#ifdef LIBXML_HTML_ENABLED
-#define gen_nb_const_htmlNodePtr 1
-static htmlNodePtr gen_const_htmlNodePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
- return(NULL);
-}
-static void des_const_htmlNodePtr(int no ATTRIBUTE_UNUSED, const htmlNodePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
-}
-#endif
-
#ifdef LIBXML_HTML_ENABLED
#define gen_nb_htmlDocPtr 3
static htmlDocPtr gen_htmlDocPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
@@ -1007,6 +983,13 @@ static void des_void_ptr_ptr(int no ATTRIBUTE_UNUSED, void ** val ATTRIBUTE_UNUS
}
#endif
+#define gen_nb_xmlParserInputPtr 1
+static xmlParserInputPtr gen_xmlParserInputPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+ return(NULL);
+}
+static void des_xmlParserInputPtr(int no ATTRIBUTE_UNUSED, xmlParserInputPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
/************************************************************************
* *
* WARNING: end of the manually maintained part of the test code *
@@ -1313,7 +1296,7 @@ test_UTF8ToHtml(void) {
int n_out;
int * outlen; /* the length of @out */
int n_outlen;
- unsigned char * in; /* a pointer to an array of UTF-8 chars */
+ const unsigned char * in; /* a pointer to an array of UTF-8 chars */
int n_in;
int * inlen; /* the length of @in */
int n_inlen;
@@ -1328,12 +1311,12 @@ test_UTF8ToHtml(void) {
in = gen_const_unsigned_char_ptr(n_in, 2);
inlen = gen_int_ptr(n_inlen, 3);
- ret_val = UTF8ToHtml(out, outlen, (const unsigned char *)in, inlen);
+ ret_val = UTF8ToHtml(out, outlen, in, inlen);
desret_int(ret_val);
call_tests++;
des_unsigned_char_ptr(n_out, out, 0);
des_int_ptr(n_outlen, outlen, 1);
- des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 2);
+ des_const_unsigned_char_ptr(n_in, in, 2);
des_int_ptr(n_inlen, inlen, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -1371,9 +1354,9 @@ test_htmlAttrAllowed(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlStatus ret_val;
- htmlElemDesc * elt; /* HTML element */
+ const htmlElemDesc * elt; /* HTML element */
int n_elt;
- xmlChar * attr; /* HTML attribute */
+ const xmlChar * attr; /* HTML attribute */
int n_attr;
int legacy; /* whether to allow deprecated attributes */
int n_legacy;
@@ -1386,11 +1369,11 @@ test_htmlAttrAllowed(void) {
attr = gen_const_xmlChar_ptr(n_attr, 1);
legacy = gen_int(n_legacy, 2);
- ret_val = htmlAttrAllowed((const htmlElemDesc *)elt, (const xmlChar *)attr, legacy);
+ ret_val = htmlAttrAllowed(elt, attr, legacy);
desret_htmlStatus(ret_val);
call_tests++;
- des_const_htmlElemDesc_ptr(n_elt, (const htmlElemDesc *)elt, 0);
- des_const_xmlChar_ptr(n_attr, (const xmlChar *)attr, 1);
+ des_const_htmlElemDesc_ptr(n_elt, elt, 0);
+ des_const_xmlChar_ptr(n_attr, attr, 1);
des_int(n_legacy, legacy, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -1428,7 +1411,7 @@ test_htmlAutoCloseTag(void) {
int ret_val;
htmlDocPtr doc; /* the HTML document */
int n_doc;
- xmlChar * name; /* The tag name */
+ const xmlChar * name; /* The tag name */
int n_name;
htmlNodePtr elem; /* the HTML element */
int n_elem;
@@ -1441,11 +1424,11 @@ test_htmlAutoCloseTag(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
elem = gen_htmlNodePtr(n_elem, 2);
- ret_val = htmlAutoCloseTag(doc, (const xmlChar *)name, elem);
+ ret_val = htmlAutoCloseTag(doc, name, elem);
desret_int(ret_val);
call_tests++;
des_htmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_htmlNodePtr(n_elem, elem, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -1476,7 +1459,7 @@ test_htmlCreateFileParserCtxt(void) {
htmlParserCtxtPtr ret_val;
const char * filename; /* the filename */
int n_filename;
- char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+ const char * encoding; /* optional encoding */
int n_encoding;
for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
@@ -1485,11 +1468,11 @@ test_htmlCreateFileParserCtxt(void) {
filename = gen_fileoutput(n_filename, 0);
encoding = gen_const_char_ptr(n_encoding, 1);
- ret_val = htmlCreateFileParserCtxt(filename, (const char *)encoding);
+ ret_val = htmlCreateFileParserCtxt(filename, encoding);
desret_htmlParserCtxtPtr(ret_val);
call_tests++;
des_fileoutput(n_filename, filename, 0);
- des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+ des_const_char_ptr(n_encoding, encoding, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlCreateFileParserCtxt",
@@ -1515,7 +1498,7 @@ test_htmlCreateMemoryParserCtxt(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlParserCtxtPtr ret_val;
- char * buffer; /* a pointer to a char array */
+ const char * buffer; /* a pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
@@ -1529,10 +1512,10 @@ test_htmlCreateMemoryParserCtxt(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = htmlCreateMemoryParserCtxt((const char *)buffer, size);
+ ret_val = htmlCreateMemoryParserCtxt(buffer, size);
desret_htmlParserCtxtPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+ des_const_char_ptr(n_buffer, buffer, 0);
des_int(n_size, size, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -1566,17 +1549,17 @@ test_htmlCreatePushParserCtxt(void) {
#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_PUSH_ENABLED)
int mem_base;
htmlParserCtxtPtr ret_val;
- htmlSAXHandlerPtr sax; /* a SAX handler */
+ htmlSAXHandlerPtr sax; /* a SAX handler (optional) */
int n_sax;
- void * user_data; /* The user data returned on SAX callbacks */
+ void * user_data; /* The user data returned on SAX callbacks (optional) */
int n_user_data;
- char * chunk; /* a pointer to an array of chars */
+ const char * chunk; /* a pointer to an array of chars (optional) */
int n_chunk;
int size; /* number of chars in the array */
int n_size;
- const char * filename; /* an optional file name or URI */
+ const char * filename; /* only used for error reporting (optional) */
int n_filename;
- xmlCharEncoding enc; /* an optional encoding */
+ xmlCharEncoding enc; /* encoding (deprecated, pass XML_CHAR_ENCODING_NONE) */
int n_enc;
for (n_sax = 0;n_sax < gen_nb_htmlSAXHandlerPtr;n_sax++) {
@@ -1596,12 +1579,12 @@ test_htmlCreatePushParserCtxt(void) {
(size > xmlStrlen(BAD_CAST chunk)))
size = 0;
- ret_val = htmlCreatePushParserCtxt(sax, user_data, (const char *)chunk, size, filename, enc);
+ ret_val = htmlCreatePushParserCtxt(sax, user_data, chunk, size, filename, enc);
desret_htmlParserCtxtPtr(ret_val);
call_tests++;
des_htmlSAXHandlerPtr(n_sax, sax, 0);
des_userdata(n_user_data, user_data, 1);
- des_const_char_ptr(n_chunk, (const char *)chunk, 2);
+ des_const_char_ptr(n_chunk, chunk, 2);
des_int(n_size, size, 3);
des_fileoutput(n_filename, filename, 4);
des_xmlCharEncoding(n_enc, enc, 5);
@@ -1631,6 +1614,47 @@ test_htmlCreatePushParserCtxt(void) {
}
+static int
+test_htmlCtxtParseDocument(void) {
+ int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+ int mem_base;
+ htmlDocPtr ret_val;
+ htmlParserCtxtPtr ctxt; /* an HTML parser context */
+ int n_ctxt;
+ xmlParserInputPtr input; /* parser input */
+ int n_input;
+
+ for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+ for (n_input = 0;n_input < gen_nb_xmlParserInputPtr;n_input++) {
+ mem_base = xmlMemBlocks();
+ ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+ input = gen_xmlParserInputPtr(n_input, 1);
+
+ ret_val = htmlCtxtParseDocument(ctxt, input);
+ desret_htmlDocPtr(ret_val);
+ call_tests++;
+ des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+ des_xmlParserInputPtr(n_input, input, 1);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in htmlCtxtParseDocument",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_ctxt);
+ printf(" %d", n_input);
+ printf("\n");
+ }
+ }
+ }
+ function_tests++;
+#endif
+
+ return(test_ret);
+}
+
+
static int
test_htmlCtxtReadDoc(void) {
int test_ret = 0;
@@ -1640,34 +1664,34 @@ test_htmlCtxtReadDoc(void) {
htmlDocPtr ret_val;
htmlParserCtxtPtr ctxt; /* an HTML parser context */
int n_ctxt;
- xmlChar * str; /* a pointer to a zero terminated string */
+ const xmlChar * str; /* a pointer to a zero terminated string */
int n_str;
- const char * URL; /* the base URL to use for the document */
+ const char * URL; /* only used for error reporting (optional) */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
- int options; /* a combination of htmlParserOption(s) */
+ int options; /* a combination of htmlParserOptions */
int n_options;
for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
- for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+ for (n_URL = 0;n_URL < gen_nb_const_char_ptr;n_URL++) {
for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
for (n_options = 0;n_options < gen_nb_int;n_options++) {
mem_base = xmlMemBlocks();
ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
str = gen_const_xmlChar_ptr(n_str, 1);
- URL = gen_filepath(n_URL, 2);
+ URL = gen_const_char_ptr(n_URL, 2);
encoding = gen_const_char_ptr(n_encoding, 3);
options = gen_int(n_options, 4);
- ret_val = htmlCtxtReadDoc(ctxt, (const xmlChar *)str, URL, (const char *)encoding, options);
+ ret_val = htmlCtxtReadDoc(ctxt, str, URL, encoding, options);
desret_htmlDocPtr(ret_val);
call_tests++;
des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
- des_filepath(n_URL, URL, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_const_xmlChar_ptr(n_str, str, 1);
+ des_const_char_ptr(n_URL, URL, 2);
+ des_const_char_ptr(n_encoding, encoding, 3);
des_int(n_options, options, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -1703,9 +1727,9 @@ test_htmlCtxtReadFile(void) {
int n_ctxt;
const char * filename; /* a file or URL */
int n_filename;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
- int options; /* a combination of htmlParserOption(s) */
+ int options; /* a combination of htmlParserOptions */
int n_options;
for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
@@ -1717,12 +1741,12 @@ test_htmlCtxtReadFile(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
options = gen_int(n_options, 3);
- ret_val = htmlCtxtReadFile(ctxt, filename, (const char *)encoding, options);
+ ret_val = htmlCtxtReadFile(ctxt, filename, encoding, options);
desret_htmlDocPtr(ret_val);
call_tests++;
des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
des_filepath(n_filename, filename, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_int(n_options, options, 3);
xmlResetLastError();
}
@@ -1745,42 +1769,42 @@ test_htmlCtxtReadMemory(void) {
htmlDocPtr ret_val;
htmlParserCtxtPtr ctxt; /* an HTML parser context */
int n_ctxt;
- char * buffer; /* a pointer to a char array */
+ const char * buffer; /* a pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
- const char * URL; /* the base URL to use for the document */
+ const char * URL; /* only used for error reporting (optional) */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding (optinal) */
int n_encoding;
- int options; /* a combination of htmlParserOption(s) */
+ int options; /* a combination of htmlParserOptions */
int n_options;
for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
for (n_size = 0;n_size < gen_nb_int;n_size++) {
- for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+ for (n_URL = 0;n_URL < gen_nb_const_char_ptr;n_URL++) {
for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
for (n_options = 0;n_options < gen_nb_int;n_options++) {
mem_base = xmlMemBlocks();
ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
buffer = gen_const_char_ptr(n_buffer, 1);
size = gen_int(n_size, 2);
- URL = gen_filepath(n_URL, 3);
+ URL = gen_const_char_ptr(n_URL, 3);
encoding = gen_const_char_ptr(n_encoding, 4);
options = gen_int(n_options, 5);
if ((buffer != NULL) &&
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = htmlCtxtReadMemory(ctxt, (const char *)buffer, size, URL, (const char *)encoding, options);
+ ret_val = htmlCtxtReadMemory(ctxt, buffer, size, URL, encoding, options);
desret_htmlDocPtr(ret_val);
call_tests++;
des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+ des_const_char_ptr(n_buffer, buffer, 1);
des_int(n_size, size, 2);
- des_filepath(n_URL, URL, 3);
- des_const_char_ptr(n_encoding, (const char *)encoding, 4);
+ des_const_char_ptr(n_URL, URL, 3);
+ des_const_char_ptr(n_encoding, encoding, 4);
des_int(n_options, options, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -1888,9 +1912,9 @@ test_htmlElementAllowedHere(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
int ret_val;
- htmlElemDesc * parent; /* HTML parent element */
+ const htmlElemDesc * parent; /* HTML parent element */
int n_parent;
- xmlChar * elt; /* HTML element */
+ const xmlChar * elt; /* HTML element */
int n_elt;
for (n_parent = 0;n_parent < gen_nb_const_htmlElemDesc_ptr;n_parent++) {
@@ -1899,11 +1923,11 @@ test_htmlElementAllowedHere(void) {
parent = gen_const_htmlElemDesc_ptr(n_parent, 0);
elt = gen_const_xmlChar_ptr(n_elt, 1);
- ret_val = htmlElementAllowedHere((const htmlElemDesc *)parent, (const xmlChar *)elt);
+ ret_val = htmlElementAllowedHere(parent, elt);
desret_int(ret_val);
call_tests++;
- des_const_htmlElemDesc_ptr(n_parent, (const htmlElemDesc *)parent, 0);
- des_const_xmlChar_ptr(n_elt, (const xmlChar *)elt, 1);
+ des_const_htmlElemDesc_ptr(n_parent, parent, 0);
+ des_const_xmlChar_ptr(n_elt, elt, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlElementAllowedHere",
@@ -1929,9 +1953,9 @@ test_htmlElementStatusHere(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlStatus ret_val;
- htmlElemDesc * parent; /* HTML parent element */
+ const htmlElemDesc * parent; /* HTML parent element */
int n_parent;
- htmlElemDesc * elt; /* HTML element */
+ const htmlElemDesc * elt; /* HTML element */
int n_elt;
for (n_parent = 0;n_parent < gen_nb_const_htmlElemDesc_ptr;n_parent++) {
@@ -1940,11 +1964,11 @@ test_htmlElementStatusHere(void) {
parent = gen_const_htmlElemDesc_ptr(n_parent, 0);
elt = gen_const_htmlElemDesc_ptr(n_elt, 1);
- ret_val = htmlElementStatusHere((const htmlElemDesc *)parent, (const htmlElemDesc *)elt);
+ ret_val = htmlElementStatusHere(parent, elt);
desret_htmlStatus(ret_val);
call_tests++;
- des_const_htmlElemDesc_ptr(n_parent, (const htmlElemDesc *)parent, 0);
- des_const_htmlElemDesc_ptr(n_elt, (const htmlElemDesc *)elt, 1);
+ des_const_htmlElemDesc_ptr(n_parent, parent, 0);
+ des_const_htmlElemDesc_ptr(n_elt, elt, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlElementStatusHere",
@@ -1974,7 +1998,7 @@ test_htmlEncodeEntities(void) {
int n_out;
int * outlen; /* the length of @out */
int n_outlen;
- unsigned char * in; /* a pointer to an array of UTF-8 chars */
+ const unsigned char * in; /* a pointer to an array of UTF-8 chars */
int n_in;
int * inlen; /* the length of @in */
int n_inlen;
@@ -1993,12 +2017,12 @@ test_htmlEncodeEntities(void) {
inlen = gen_int_ptr(n_inlen, 3);
quoteChar = gen_int(n_quoteChar, 4);
- ret_val = htmlEncodeEntities(out, outlen, (const unsigned char *)in, inlen, quoteChar);
+ ret_val = htmlEncodeEntities(out, outlen, in, inlen, quoteChar);
desret_int(ret_val);
call_tests++;
des_unsigned_char_ptr(n_out, out, 0);
des_int_ptr(n_outlen, outlen, 1);
- des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 2);
+ des_const_unsigned_char_ptr(n_in, in, 2);
des_int_ptr(n_inlen, inlen, 3);
des_int(n_quoteChar, quoteChar, 4);
xmlResetLastError();
@@ -2032,17 +2056,17 @@ test_htmlEntityLookup(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
const htmlEntityDesc * ret_val;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
mem_base = xmlMemBlocks();
name = gen_const_xmlChar_ptr(n_name, 0);
- ret_val = htmlEntityLookup((const xmlChar *)name);
+ ret_val = htmlEntityLookup(name);
desret_const_htmlEntityDesc_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+ des_const_xmlChar_ptr(n_name, name, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlEntityLookup",
@@ -2200,17 +2224,17 @@ test_htmlIsScriptAttribute(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
int ret_val;
- xmlChar * name; /* an attribute name */
+ const xmlChar * name; /* an attribute name */
int n_name;
for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
mem_base = xmlMemBlocks();
name = gen_const_xmlChar_ptr(n_name, 0);
- ret_val = htmlIsScriptAttribute((const xmlChar *)name);
+ ret_val = htmlIsScriptAttribute(name);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+ des_const_xmlChar_ptr(n_name, name, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlIsScriptAttribute",
@@ -2268,7 +2292,7 @@ test_htmlNewSAXParserCtxt(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlParserCtxtPtr ret_val;
- htmlSAXHandler * sax; /* SAX handler */
+ const htmlSAXHandler * sax; /* SAX handler */
int n_sax;
void * userData; /* user data */
int n_userData;
@@ -2279,10 +2303,10 @@ test_htmlNewSAXParserCtxt(void) {
sax = gen_const_htmlSAXHandler_ptr(n_sax, 0);
userData = gen_userdata(n_userData, 1);
- ret_val = htmlNewSAXParserCtxt((const htmlSAXHandler *)sax, userData);
+ ret_val = htmlNewSAXParserCtxt(sax, userData);
desret_htmlParserCtxtPtr(ret_val);
call_tests++;
- des_const_htmlSAXHandler_ptr(n_sax, (const htmlSAXHandler *)sax, 0);
+ des_const_htmlSAXHandler_ptr(n_sax, sax, 0);
des_userdata(n_userData, userData, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -2314,16 +2338,16 @@ test_htmlNodeStatus(void) {
int legacy; /* whether to allow deprecated elements (YES is faster here for Element nodes) */
int n_legacy;
- for (n_node = 0;n_node < gen_nb_const_htmlNodePtr;n_node++) {
+ for (n_node = 0;n_node < gen_nb_htmlNodePtr;n_node++) {
for (n_legacy = 0;n_legacy < gen_nb_int;n_legacy++) {
mem_base = xmlMemBlocks();
- node = gen_const_htmlNodePtr(n_node, 0);
+ node = gen_htmlNodePtr(n_node, 0);
legacy = gen_int(n_legacy, 1);
- ret_val = htmlNodeStatus((const htmlNodePtr)node, legacy);
+ ret_val = htmlNodeStatus(node, legacy);
desret_htmlStatus(ret_val);
call_tests++;
- des_const_htmlNodePtr(n_node, (const htmlNodePtr)node, 0);
+ des_htmlNodePtr(n_node, node, 0);
des_int(n_legacy, legacy, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -2386,9 +2410,9 @@ test_htmlParseChunk(void) {
int ret_val;
htmlParserCtxtPtr ctxt; /* an HTML parser context */
int n_ctxt;
- char * chunk; /* an char array */
+ const char * chunk; /* chunk of memory */
int n_chunk;
- int size; /* the size in byte of the chunk */
+ int size; /* size of chunk in bytes */
int n_size;
int terminate; /* last chunk indicator */
int n_terminate;
@@ -2406,12 +2430,12 @@ test_htmlParseChunk(void) {
(size > xmlStrlen(BAD_CAST chunk)))
size = 0;
- ret_val = htmlParseChunk(ctxt, (const char *)chunk, size, terminate);
+ ret_val = htmlParseChunk(ctxt, chunk, size, terminate);
if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}
desret_int(ret_val);
call_tests++;
des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_char_ptr(n_chunk, (const char *)chunk, 1);
+ des_const_char_ptr(n_chunk, chunk, 1);
des_int(n_size, size, 2);
des_int(n_terminate, terminate, 3);
xmlResetLastError();
@@ -2443,9 +2467,9 @@ test_htmlParseDoc(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlDocPtr ret_val;
- xmlChar * cur; /* a pointer to an array of xmlChar */
+ const xmlChar * cur; /* a pointer to an array of xmlChar */
int n_cur;
- char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+ const char * encoding; /* the encoding (optional) */
int n_encoding;
for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
@@ -2454,11 +2478,11 @@ test_htmlParseDoc(void) {
cur = gen_const_xmlChar_ptr(n_cur, 0);
encoding = gen_const_char_ptr(n_encoding, 1);
- ret_val = htmlParseDoc((const xmlChar *)cur, (const char *)encoding);
+ ret_val = htmlParseDoc(cur, encoding);
desret_htmlDocPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
- des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+ des_const_xmlChar_ptr(n_cur, cur, 0);
+ des_const_char_ptr(n_encoding, encoding, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlParseDoc",
@@ -2553,7 +2577,7 @@ test_htmlParseEntityRef(void) {
const htmlEntityDesc * ret_val;
htmlParserCtxtPtr ctxt; /* an HTML parser context */
int n_ctxt;
- xmlChar ** str; /* location to store the entity name */
+ const xmlChar ** str; /* location to store the entity name */
int n_str;
for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
@@ -2562,11 +2586,11 @@ test_htmlParseEntityRef(void) {
ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
str = gen_const_xmlChar_ptr_ptr(n_str, 1);
- ret_val = htmlParseEntityRef(ctxt, (const xmlChar **)str);
+ ret_val = htmlParseEntityRef(ctxt, str);
desret_const_htmlEntityDesc_ptr(ret_val);
call_tests++;
des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr_ptr(n_str, (const xmlChar **)str, 1);
+ des_const_xmlChar_ptr_ptr(n_str, str, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlParseEntityRef",
@@ -2593,7 +2617,7 @@ test_htmlParseFile(void) {
htmlDocPtr ret_val;
const char * filename; /* the filename */
int n_filename;
- char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+ const char * encoding; /* encoding (optional) */
int n_encoding;
for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
@@ -2601,11 +2625,11 @@ test_htmlParseFile(void) {
filename = gen_filepath(n_filename, 0);
encoding = gen_const_char_ptr(n_encoding, 1);
- ret_val = htmlParseFile(filename, (const char *)encoding);
+ ret_val = htmlParseFile(filename, encoding);
desret_htmlDocPtr(ret_val);
call_tests++;
des_filepath(n_filename, filename, 0);
- des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+ des_const_char_ptr(n_encoding, encoding, 1);
xmlResetLastError();
}
}
@@ -2623,39 +2647,39 @@ test_htmlReadDoc(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlDocPtr ret_val;
- xmlChar * cur; /* a pointer to a zero terminated string */
- int n_cur;
- const char * URL; /* the base URL to use for the document */
- int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const xmlChar * str; /* a pointer to a zero terminated string */
+ int n_str;
+ const char * url; /* only used for error reporting (optoinal) */
+ int n_url;
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
- int options; /* a combination of htmlParserOption(s) */
+ int options; /* a combination of htmlParserOptions */
int n_options;
- for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
- for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+ for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+ for (n_url = 0;n_url < gen_nb_const_char_ptr;n_url++) {
for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
for (n_options = 0;n_options < gen_nb_int;n_options++) {
mem_base = xmlMemBlocks();
- cur = gen_const_xmlChar_ptr(n_cur, 0);
- URL = gen_filepath(n_URL, 1);
+ str = gen_const_xmlChar_ptr(n_str, 0);
+ url = gen_const_char_ptr(n_url, 1);
encoding = gen_const_char_ptr(n_encoding, 2);
options = gen_int(n_options, 3);
- ret_val = htmlReadDoc((const xmlChar *)cur, URL, (const char *)encoding, options);
+ ret_val = htmlReadDoc(str, url, encoding, options);
desret_htmlDocPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
- des_filepath(n_URL, URL, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_xmlChar_ptr(n_str, str, 0);
+ des_const_char_ptr(n_url, url, 1);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_int(n_options, options, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlReadDoc",
xmlMemBlocks() - mem_base);
test_ret++;
- printf(" %d", n_cur);
- printf(" %d", n_URL);
+ printf(" %d", n_str);
+ printf(" %d", n_url);
printf(" %d", n_encoding);
printf(" %d", n_options);
printf("\n");
@@ -2680,9 +2704,9 @@ test_htmlReadFile(void) {
htmlDocPtr ret_val;
const char * filename; /* a file or URL */
int n_filename;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
- int options; /* a combination of htmlParserOption(s) */
+ int options; /* a combination of htmlParserOptions */
int n_options;
for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
@@ -2693,11 +2717,11 @@ test_htmlReadFile(void) {
encoding = gen_const_char_ptr(n_encoding, 1);
options = gen_int(n_options, 2);
- ret_val = htmlReadFile(filename, (const char *)encoding, options);
+ ret_val = htmlReadFile(filename, encoding, options);
desret_htmlDocPtr(ret_val);
call_tests++;
des_filepath(n_filename, filename, 0);
- des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+ des_const_char_ptr(n_encoding, encoding, 1);
des_int(n_options, options, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -2726,39 +2750,39 @@ test_htmlReadMemory(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlDocPtr ret_val;
- char * buffer; /* a pointer to a char array */
+ const char * buffer; /* a pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
- const char * URL; /* the base URL to use for the document */
- int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * url; /* only used for error reporting (optional) */
+ int n_url;
+ const char * encoding; /* the document encoding, or NULL */
int n_encoding;
int options; /* a combination of htmlParserOption(s) */
int n_options;
for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
for (n_size = 0;n_size < gen_nb_int;n_size++) {
- for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+ for (n_url = 0;n_url < gen_nb_const_char_ptr;n_url++) {
for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
for (n_options = 0;n_options < gen_nb_int;n_options++) {
mem_base = xmlMemBlocks();
buffer = gen_const_char_ptr(n_buffer, 0);
size = gen_int(n_size, 1);
- URL = gen_filepath(n_URL, 2);
+ url = gen_const_char_ptr(n_url, 2);
encoding = gen_const_char_ptr(n_encoding, 3);
options = gen_int(n_options, 4);
if ((buffer != NULL) &&
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = htmlReadMemory((const char *)buffer, size, URL, (const char *)encoding, options);
+ ret_val = htmlReadMemory(buffer, size, url, encoding, options);
desret_htmlDocPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+ des_const_char_ptr(n_buffer, buffer, 0);
des_int(n_size, size, 1);
- des_filepath(n_URL, URL, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_const_char_ptr(n_url, url, 2);
+ des_const_char_ptr(n_encoding, encoding, 3);
des_int(n_options, options, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -2767,7 +2791,7 @@ test_htmlReadMemory(void) {
test_ret++;
printf(" %d", n_buffer);
printf(" %d", n_size);
- printf(" %d", n_URL);
+ printf(" %d", n_url);
printf(" %d", n_encoding);
printf(" %d", n_options);
printf("\n");
@@ -2791,9 +2815,9 @@ test_htmlSAXParseDoc(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlDocPtr ret_val;
- xmlChar * cur; /* a pointer to an array of xmlChar */
+ const xmlChar * cur; /* a pointer to an array of xmlChar */
int n_cur;
- char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+ const char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
int n_encoding;
htmlSAXHandlerPtr sax; /* the SAX handler block */
int n_sax;
@@ -2810,11 +2834,11 @@ test_htmlSAXParseDoc(void) {
sax = gen_htmlSAXHandlerPtr(n_sax, 2);
userData = gen_userdata(n_userData, 3);
- ret_val = htmlSAXParseDoc((const xmlChar *)cur, (const char *)encoding, sax, userData);
+ ret_val = htmlSAXParseDoc(cur, encoding, sax, userData);
desret_htmlDocPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
- des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+ des_const_xmlChar_ptr(n_cur, cur, 0);
+ des_const_char_ptr(n_encoding, encoding, 1);
des_htmlSAXHandlerPtr(n_sax, sax, 2);
des_userdata(n_userData, userData, 3);
xmlResetLastError();
@@ -2848,7 +2872,7 @@ test_htmlSAXParseFile(void) {
htmlDocPtr ret_val;
const char * filename; /* the filename */
int n_filename;
- char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+ const char * encoding; /* encoding (optional) */
int n_encoding;
htmlSAXHandlerPtr sax; /* the SAX handler block */
int n_sax;
@@ -2865,11 +2889,11 @@ test_htmlSAXParseFile(void) {
sax = gen_htmlSAXHandlerPtr(n_sax, 2);
userData = gen_userdata(n_userData, 3);
- ret_val = htmlSAXParseFile(filename, (const char *)encoding, sax, userData);
+ ret_val = htmlSAXParseFile(filename, encoding, sax, userData);
desret_htmlDocPtr(ret_val);
call_tests++;
des_filepath(n_filename, filename, 0);
- des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+ des_const_char_ptr(n_encoding, encoding, 1);
des_htmlSAXHandlerPtr(n_sax, sax, 2);
des_userdata(n_userData, userData, 3);
xmlResetLastError();
@@ -2907,13 +2931,14 @@ static int
test_HTMLparser(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing HTMLparser : 35 of 41 functions ...\n");
+ if (quiet == 0) printf("Testing HTMLparser : 36 of 42 functions ...\n");
test_ret += test_UTF8ToHtml();
test_ret += test_htmlAttrAllowed();
test_ret += test_htmlAutoCloseTag();
test_ret += test_htmlCreateFileParserCtxt();
test_ret += test_htmlCreateMemoryParserCtxt();
test_ret += test_htmlCreatePushParserCtxt();
+ test_ret += test_htmlCtxtParseDocument();
test_ret += test_htmlCtxtReadDoc();
test_ret += test_htmlCtxtReadFile();
test_ret += test_htmlCtxtReadMemory();
@@ -2960,7 +2985,7 @@ test_htmlDocContentDumpFormatOutput(void) {
int n_buf;
xmlDocPtr cur; /* the document */
int n_cur;
- char * encoding; /* the encoding string (unused) */
+ const char * encoding; /* the encoding string (unused) */
int n_encoding;
int format; /* should formatting spaces been added */
int n_format;
@@ -2975,11 +3000,11 @@ test_htmlDocContentDumpFormatOutput(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
format = gen_int(n_format, 3);
- htmlDocContentDumpFormatOutput(buf, cur, (const char *)encoding, format);
+ htmlDocContentDumpFormatOutput(buf, cur, encoding, format);
call_tests++;
des_xmlOutputBufferPtr(n_buf, buf, 0);
des_xmlDocPtr(n_cur, cur, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_int(n_format, format, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -3013,7 +3038,7 @@ test_htmlDocContentDumpOutput(void) {
int n_buf;
xmlDocPtr cur; /* the document */
int n_cur;
- char * encoding; /* the encoding string (unused) */
+ const char * encoding; /* the encoding string (unused) */
int n_encoding;
for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
@@ -3024,11 +3049,11 @@ test_htmlDocContentDumpOutput(void) {
cur = gen_xmlDocPtr(n_cur, 1);
encoding = gen_const_char_ptr(n_encoding, 2);
- htmlDocContentDumpOutput(buf, cur, (const char *)encoding);
+ htmlDocContentDumpOutput(buf, cur, encoding);
call_tests++;
des_xmlOutputBufferPtr(n_buf, buf, 0);
des_xmlDocPtr(n_cur, cur, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlDocContentDumpOutput",
@@ -3234,17 +3259,17 @@ test_htmlIsBooleanAttr(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
int ret_val;
- xmlChar * name; /* the name of the attribute to check */
+ const xmlChar * name; /* the name of the attribute to check */
int n_name;
for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
mem_base = xmlMemBlocks();
name = gen_const_xmlChar_ptr(n_name, 0);
- ret_val = htmlIsBooleanAttr((const xmlChar *)name);
+ ret_val = htmlIsBooleanAttr(name);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+ des_const_xmlChar_ptr(n_name, name, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlIsBooleanAttr",
@@ -3268,9 +3293,9 @@ test_htmlNewDoc(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlDocPtr ret_val;
- xmlChar * URI; /* URI for the dtd, or NULL */
+ const xmlChar * URI; /* URI for the dtd, or NULL */
int n_URI;
- xmlChar * ExternalID; /* the external ID of the DTD, or NULL */
+ const xmlChar * ExternalID; /* the external ID of the DTD, or NULL */
int n_ExternalID;
for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
@@ -3279,11 +3304,11 @@ test_htmlNewDoc(void) {
URI = gen_const_xmlChar_ptr(n_URI, 0);
ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 1);
- ret_val = htmlNewDoc((const xmlChar *)URI, (const xmlChar *)ExternalID);
+ ret_val = htmlNewDoc(URI, ExternalID);
desret_htmlDocPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 1);
+ des_const_xmlChar_ptr(n_URI, URI, 0);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlNewDoc",
@@ -3309,9 +3334,9 @@ test_htmlNewDocNoDtD(void) {
#if defined(LIBXML_HTML_ENABLED)
int mem_base;
htmlDocPtr ret_val;
- xmlChar * URI; /* URI for the dtd, or NULL */
+ const xmlChar * URI; /* URI for the dtd, or NULL */
int n_URI;
- xmlChar * ExternalID; /* the external ID of the DTD, or NULL */
+ const xmlChar * ExternalID; /* the external ID of the DTD, or NULL */
int n_ExternalID;
for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
@@ -3320,11 +3345,11 @@ test_htmlNewDocNoDtD(void) {
URI = gen_const_xmlChar_ptr(n_URI, 0);
ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 1);
- ret_val = htmlNewDocNoDtD((const xmlChar *)URI, (const xmlChar *)ExternalID);
+ ret_val = htmlNewDocNoDtD(URI, ExternalID);
desret_htmlDocPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 1);
+ des_const_xmlChar_ptr(n_URI, URI, 0);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlNewDocNoDtD",
@@ -3450,7 +3475,7 @@ test_htmlNodeDumpFileFormat(void) {
int n_doc;
xmlNodePtr cur; /* the current node */
int n_cur;
- char * encoding; /* the document encoding */
+ const char * encoding; /* the document encoding */
int n_encoding;
int format; /* should formatting spaces been added */
int n_format;
@@ -3467,13 +3492,13 @@ test_htmlNodeDumpFileFormat(void) {
encoding = gen_const_char_ptr(n_encoding, 3);
format = gen_int(n_format, 4);
- ret_val = htmlNodeDumpFileFormat(out, doc, cur, (const char *)encoding, format);
+ ret_val = htmlNodeDumpFileFormat(out, doc, cur, encoding, format);
desret_int(ret_val);
call_tests++;
des_FILE_ptr(n_out, out, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlNodePtr(n_cur, cur, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_const_char_ptr(n_encoding, encoding, 3);
des_int(n_format, format, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -3511,7 +3536,7 @@ test_htmlNodeDumpFormatOutput(void) {
int n_doc;
xmlNodePtr cur; /* the current node */
int n_cur;
- char * encoding; /* the encoding string (unused) */
+ const char * encoding; /* the encoding string (unused) */
int n_encoding;
int format; /* should formatting spaces been added */
int n_format;
@@ -3528,12 +3553,12 @@ test_htmlNodeDumpFormatOutput(void) {
encoding = gen_const_char_ptr(n_encoding, 3);
format = gen_int(n_format, 4);
- htmlNodeDumpFormatOutput(buf, doc, cur, (const char *)encoding, format);
+ htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
call_tests++;
des_xmlOutputBufferPtr(n_buf, buf, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlNodePtr(n_cur, cur, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_const_char_ptr(n_encoding, encoding, 3);
des_int(n_format, format, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -3571,7 +3596,7 @@ test_htmlNodeDumpOutput(void) {
int n_doc;
xmlNodePtr cur; /* the current node */
int n_cur;
- char * encoding; /* the encoding string (unused) */
+ const char * encoding; /* the encoding string (unused) */
int n_encoding;
for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
@@ -3584,12 +3609,12 @@ test_htmlNodeDumpOutput(void) {
cur = gen_xmlNodePtr(n_cur, 2);
encoding = gen_const_char_ptr(n_encoding, 3);
- htmlNodeDumpOutput(buf, doc, cur, (const char *)encoding);
+ htmlNodeDumpOutput(buf, doc, cur, encoding);
call_tests++;
des_xmlOutputBufferPtr(n_buf, buf, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlNodePtr(n_cur, cur, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_const_char_ptr(n_encoding, encoding, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlNodeDumpOutput",
@@ -3664,7 +3689,7 @@ test_htmlSaveFileEnc(void) {
int n_filename;
xmlDocPtr cur; /* the document */
int n_cur;
- char * encoding; /* the document encoding */
+ const char * encoding; /* the document encoding */
int n_encoding;
for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
@@ -3675,12 +3700,12 @@ test_htmlSaveFileEnc(void) {
cur = gen_xmlDocPtr(n_cur, 1);
encoding = gen_const_char_ptr(n_encoding, 2);
- ret_val = htmlSaveFileEnc(filename, cur, (const char *)encoding);
+ ret_val = htmlSaveFileEnc(filename, cur, encoding);
desret_int(ret_val);
call_tests++;
des_fileoutput(n_filename, filename, 0);
des_xmlDocPtr(n_cur, cur, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlSaveFileEnc",
@@ -3712,7 +3737,7 @@ test_htmlSaveFileFormat(void) {
int n_filename;
xmlDocPtr cur; /* the document */
int n_cur;
- char * encoding; /* the document encoding */
+ const char * encoding; /* the document encoding */
int n_encoding;
int format; /* should formatting spaces been added */
int n_format;
@@ -3727,12 +3752,12 @@ test_htmlSaveFileFormat(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
format = gen_int(n_format, 3);
- ret_val = htmlSaveFileFormat(filename, cur, (const char *)encoding, format);
+ ret_val = htmlSaveFileFormat(filename, cur, encoding, format);
desret_int(ret_val);
call_tests++;
des_fileoutput(n_filename, filename, 0);
des_xmlDocPtr(n_cur, cur, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_int(n_format, format, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -3765,7 +3790,7 @@ test_htmlSetMetaEncoding(void) {
int ret_val;
htmlDocPtr doc; /* the document */
int n_doc;
- xmlChar * encoding; /* the encoding string */
+ const xmlChar * encoding; /* the encoding string */
int n_encoding;
for (n_doc = 0;n_doc < gen_nb_htmlDocPtr;n_doc++) {
@@ -3774,11 +3799,11 @@ test_htmlSetMetaEncoding(void) {
doc = gen_htmlDocPtr(n_doc, 0);
encoding = gen_const_xmlChar_ptr(n_encoding, 1);
- ret_val = htmlSetMetaEncoding(doc, (const xmlChar *)encoding);
+ ret_val = htmlSetMetaEncoding(doc, encoding);
desret_int(ret_val);
call_tests++;
des_htmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_encoding, (const xmlChar *)encoding, 1);
+ des_const_xmlChar_ptr(n_encoding, encoding, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in htmlSetMetaEncoding",
@@ -3886,15 +3911,15 @@ test_xmlSAX2AttributeDecl(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * elem; /* the name of the element */
+ const xmlChar * elem; /* the name of the element */
int n_elem;
- xmlChar * fullname; /* the attribute name */
+ const xmlChar * fullname; /* the attribute name */
int n_fullname;
int type; /* the attribute type */
int n_type;
int def; /* the type of default value */
int n_def;
- xmlChar * defaultValue; /* the attribute default value */
+ const xmlChar * defaultValue; /* the attribute default value */
int n_defaultValue;
xmlEnumerationPtr tree; /* the tree of enumerated value set */
int n_tree;
@@ -3915,14 +3940,14 @@ test_xmlSAX2AttributeDecl(void) {
defaultValue = gen_const_xmlChar_ptr(n_defaultValue, 5);
tree = gen_xmlEnumerationPtr(n_tree, 6);
- xmlSAX2AttributeDecl(ctx, (const xmlChar *)elem, (const xmlChar *)fullname, type, def, (const xmlChar *)defaultValue, tree);
+ xmlSAX2AttributeDecl(ctx, elem, fullname, type, def, defaultValue, tree);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_elem, (const xmlChar *)elem, 1);
- des_const_xmlChar_ptr(n_fullname, (const xmlChar *)fullname, 2);
+ des_const_xmlChar_ptr(n_elem, elem, 1);
+ des_const_xmlChar_ptr(n_fullname, fullname, 2);
des_int(n_type, type, 3);
des_int(n_def, def, 4);
- des_const_xmlChar_ptr(n_defaultValue, (const xmlChar *)defaultValue, 5);
+ des_const_xmlChar_ptr(n_defaultValue, defaultValue, 5);
des_xmlEnumerationPtr(n_tree, tree, 6);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -3958,7 +3983,7 @@ test_xmlSAX2CDataBlock(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * value; /* The pcdata content */
+ const xmlChar * value; /* The pcdata content */
int n_value;
int len; /* the block length */
int n_len;
@@ -3974,10 +3999,10 @@ test_xmlSAX2CDataBlock(void) {
(len > xmlStrlen(BAD_CAST value)))
len = 0;
- xmlSAX2CDataBlock(ctx, (const xmlChar *)value, len);
+ xmlSAX2CDataBlock(ctx, value, len);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -4005,7 +4030,7 @@ test_xmlSAX2Characters(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * ch; /* a xmlChar string */
+ const xmlChar * ch; /* a xmlChar string */
int n_ch;
int len; /* the number of xmlChar */
int n_len;
@@ -4021,10 +4046,10 @@ test_xmlSAX2Characters(void) {
(len > xmlStrlen(BAD_CAST ch)))
len = 0;
- xmlSAX2Characters(ctx, (const xmlChar *)ch, len);
+ xmlSAX2Characters(ctx, ch, len);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_ch, (const xmlChar *)ch, 1);
+ des_const_xmlChar_ptr(n_ch, ch, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -4052,7 +4077,7 @@ test_xmlSAX2Comment(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * value; /* the xmlSAX2Comment content */
+ const xmlChar * value; /* the xmlSAX2Comment content */
int n_value;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4061,10 +4086,10 @@ test_xmlSAX2Comment(void) {
ctx = gen_void_ptr(n_ctx, 0);
value = gen_const_xmlChar_ptr(n_value, 1);
- xmlSAX2Comment(ctx, (const xmlChar *)value);
+ xmlSAX2Comment(ctx, value);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2Comment",
@@ -4089,7 +4114,7 @@ test_xmlSAX2ElementDecl(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* the element name */
+ const xmlChar * name; /* the element name */
int n_name;
int type; /* the element type */
int n_type;
@@ -4106,10 +4131,10 @@ test_xmlSAX2ElementDecl(void) {
type = gen_int(n_type, 2);
content = gen_xmlElementContentPtr(n_content, 3);
- xmlSAX2ElementDecl(ctx, (const xmlChar *)name, type, content);
+ xmlSAX2ElementDecl(ctx, name, type, content);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_int(n_type, type, 2);
des_xmlElementContentPtr(n_content, content, 3);
xmlResetLastError();
@@ -4172,7 +4197,7 @@ test_xmlSAX2EndElement(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* The element name */
+ const xmlChar * name; /* The element name */
int n_name;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4181,10 +4206,10 @@ test_xmlSAX2EndElement(void) {
ctx = gen_void_ptr(n_ctx, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- xmlSAX2EndElement(ctx, (const xmlChar *)name);
+ xmlSAX2EndElement(ctx, name);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2EndElement",
@@ -4211,11 +4236,11 @@ test_xmlSAX2EndElementNs(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * localname; /* the local name of the element */
+ const xmlChar * localname; /* the local name of the element */
int n_localname;
- xmlChar * prefix; /* the element namespace prefix if available */
+ const xmlChar * prefix; /* the element namespace prefix if available */
int n_prefix;
- xmlChar * URI; /* the element namespace name if available */
+ const xmlChar * URI; /* the element namespace name if available */
int n_URI;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4228,12 +4253,12 @@ test_xmlSAX2EndElementNs(void) {
prefix = gen_const_xmlChar_ptr(n_prefix, 2);
URI = gen_const_xmlChar_ptr(n_URI, 3);
- xmlSAX2EndElementNs(ctx, (const xmlChar *)localname, (const xmlChar *)prefix, (const xmlChar *)URI);
+ xmlSAX2EndElementNs(ctx, localname, prefix, URI);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_localname, (const xmlChar *)localname, 1);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 2);
- des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 3);
+ des_const_xmlChar_ptr(n_localname, localname, 1);
+ des_const_xmlChar_ptr(n_prefix, prefix, 2);
+ des_const_xmlChar_ptr(n_URI, URI, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2EndElementNs",
@@ -4262,13 +4287,13 @@ test_xmlSAX2EntityDecl(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
int type; /* the entity type */
int n_type;
- xmlChar * publicId; /* The public ID of the entity */
+ const xmlChar * publicId; /* The public ID of the entity */
int n_publicId;
- xmlChar * systemId; /* The system ID of the entity */
+ const xmlChar * systemId; /* The system ID of the entity */
int n_systemId;
xmlChar * content; /* the entity value (without processing). */
int n_content;
@@ -4287,13 +4312,13 @@ test_xmlSAX2EntityDecl(void) {
systemId = gen_const_xmlChar_ptr(n_systemId, 4);
content = gen_xmlChar_ptr(n_content, 5);
- xmlSAX2EntityDecl(ctx, (const xmlChar *)name, type, (const xmlChar *)publicId, (const xmlChar *)systemId, content);
+ xmlSAX2EntityDecl(ctx, name, type, publicId, systemId, content);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_int(n_type, type, 2);
- des_const_xmlChar_ptr(n_publicId, (const xmlChar *)publicId, 3);
- des_const_xmlChar_ptr(n_systemId, (const xmlChar *)systemId, 4);
+ des_const_xmlChar_ptr(n_publicId, publicId, 3);
+ des_const_xmlChar_ptr(n_systemId, systemId, 4);
des_xmlChar_ptr(n_content, content, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -4327,11 +4352,11 @@ test_xmlSAX2ExternalSubset(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* the root element name */
+ const xmlChar * name; /* the root element name */
int n_name;
- xmlChar * ExternalID; /* the external ID */
+ const xmlChar * ExternalID; /* the external ID */
int n_ExternalID;
- xmlChar * SystemID; /* the SYSTEM ID (e.g. filename or URL) */
+ const xmlChar * SystemID; /* the SYSTEM ID (e.g. filename or URL) */
int n_SystemID;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4344,12 +4369,12 @@ test_xmlSAX2ExternalSubset(void) {
ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 2);
SystemID = gen_const_xmlChar_ptr(n_SystemID, 3);
- xmlSAX2ExternalSubset(ctx, (const xmlChar *)name, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+ xmlSAX2ExternalSubset(ctx, name, ExternalID, SystemID);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 2);
- des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 3);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 2);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2ExternalSubset",
@@ -4411,7 +4436,7 @@ test_xmlSAX2GetEntity(void) {
xmlEntityPtr ret_val;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* The entity name */
+ const xmlChar * name; /* The entity name */
int n_name;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4420,11 +4445,11 @@ test_xmlSAX2GetEntity(void) {
ctx = gen_void_ptr(n_ctx, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlSAX2GetEntity(ctx, (const xmlChar *)name);
+ ret_val = xmlSAX2GetEntity(ctx, name);
desret_xmlEntityPtr(ret_val);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2GetEntity",
@@ -4482,7 +4507,7 @@ test_xmlSAX2GetParameterEntity(void) {
xmlEntityPtr ret_val;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* The entity name */
+ const xmlChar * name; /* The entity name */
int n_name;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4491,11 +4516,11 @@ test_xmlSAX2GetParameterEntity(void) {
ctx = gen_void_ptr(n_ctx, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlSAX2GetParameterEntity(ctx, (const xmlChar *)name);
+ ret_val = xmlSAX2GetParameterEntity(ctx, name);
desret_xmlEntityPtr(ret_val);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2GetParameterEntity",
@@ -4648,7 +4673,7 @@ test_xmlSAX2IgnorableWhitespace(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * ch; /* a xmlChar string */
+ const xmlChar * ch; /* a xmlChar string */
int n_ch;
int len; /* the number of xmlChar */
int n_len;
@@ -4664,10 +4689,10 @@ test_xmlSAX2IgnorableWhitespace(void) {
(len > xmlStrlen(BAD_CAST ch)))
len = 0;
- xmlSAX2IgnorableWhitespace(ctx, (const xmlChar *)ch, len);
+ xmlSAX2IgnorableWhitespace(ctx, ch, len);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_ch, (const xmlChar *)ch, 1);
+ des_const_xmlChar_ptr(n_ch, ch, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -4768,11 +4793,11 @@ test_xmlSAX2InternalSubset(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* the root element name */
+ const xmlChar * name; /* the root element name */
int n_name;
- xmlChar * ExternalID; /* the external ID */
+ const xmlChar * ExternalID; /* the external ID */
int n_ExternalID;
- xmlChar * SystemID; /* the SYSTEM ID (e.g. filename or URL) */
+ const xmlChar * SystemID; /* the SYSTEM ID (e.g. filename or URL) */
int n_SystemID;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4785,12 +4810,12 @@ test_xmlSAX2InternalSubset(void) {
ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 2);
SystemID = gen_const_xmlChar_ptr(n_SystemID, 3);
- xmlSAX2InternalSubset(ctx, (const xmlChar *)name, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+ xmlSAX2InternalSubset(ctx, name, ExternalID, SystemID);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 2);
- des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 3);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 2);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2InternalSubset",
@@ -4851,11 +4876,11 @@ test_xmlSAX2NotationDecl(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* The name of the notation */
+ const xmlChar * name; /* The name of the notation */
int n_name;
- xmlChar * publicId; /* The public ID of the entity */
+ const xmlChar * publicId; /* The public ID of the entity */
int n_publicId;
- xmlChar * systemId; /* The system ID of the entity */
+ const xmlChar * systemId; /* The system ID of the entity */
int n_systemId;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4868,12 +4893,12 @@ test_xmlSAX2NotationDecl(void) {
publicId = gen_const_xmlChar_ptr(n_publicId, 2);
systemId = gen_const_xmlChar_ptr(n_systemId, 3);
- xmlSAX2NotationDecl(ctx, (const xmlChar *)name, (const xmlChar *)publicId, (const xmlChar *)systemId);
+ xmlSAX2NotationDecl(ctx, name, publicId, systemId);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_publicId, (const xmlChar *)publicId, 2);
- des_const_xmlChar_ptr(n_systemId, (const xmlChar *)systemId, 3);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_publicId, publicId, 2);
+ des_const_xmlChar_ptr(n_systemId, systemId, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2NotationDecl",
@@ -4902,9 +4927,9 @@ test_xmlSAX2ProcessingInstruction(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * target; /* the target name */
+ const xmlChar * target; /* the target name */
int n_target;
- xmlChar * data; /* the PI data's */
+ const xmlChar * data; /* the PI data's */
int n_data;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4915,11 +4940,11 @@ test_xmlSAX2ProcessingInstruction(void) {
target = gen_const_xmlChar_ptr(n_target, 1);
data = gen_const_xmlChar_ptr(n_data, 2);
- xmlSAX2ProcessingInstruction(ctx, (const xmlChar *)target, (const xmlChar *)data);
+ xmlSAX2ProcessingInstruction(ctx, target, data);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_target, (const xmlChar *)target, 1);
- des_const_xmlChar_ptr(n_data, (const xmlChar *)data, 2);
+ des_const_xmlChar_ptr(n_target, target, 1);
+ des_const_xmlChar_ptr(n_data, data, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2ProcessingInstruction",
@@ -4946,7 +4971,7 @@ test_xmlSAX2Reference(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* The entity name */
+ const xmlChar * name; /* The entity name */
int n_name;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4955,10 +4980,10 @@ test_xmlSAX2Reference(void) {
ctx = gen_void_ptr(n_ctx, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- xmlSAX2Reference(ctx, (const xmlChar *)name);
+ xmlSAX2Reference(ctx, name);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2Reference",
@@ -4984,9 +5009,9 @@ test_xmlSAX2ResolveEntity(void) {
xmlParserInputPtr ret_val;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * publicId; /* The public ID of the entity */
+ const xmlChar * publicId; /* The public ID of the entity */
int n_publicId;
- xmlChar * systemId; /* The system ID of the entity */
+ const xmlChar * systemId; /* The system ID of the entity */
int n_systemId;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -4997,12 +5022,12 @@ test_xmlSAX2ResolveEntity(void) {
publicId = gen_const_xmlChar_ptr(n_publicId, 1);
systemId = gen_const_xmlChar_ptr(n_systemId, 2);
- ret_val = xmlSAX2ResolveEntity(ctx, (const xmlChar *)publicId, (const xmlChar *)systemId);
+ ret_val = xmlSAX2ResolveEntity(ctx, publicId, systemId);
desret_xmlParserInputPtr(ret_val);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_publicId, (const xmlChar *)publicId, 1);
- des_const_xmlChar_ptr(n_systemId, (const xmlChar *)systemId, 2);
+ des_const_xmlChar_ptr(n_publicId, publicId, 1);
+ des_const_xmlChar_ptr(n_systemId, systemId, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2ResolveEntity",
@@ -5102,9 +5127,9 @@ test_xmlSAX2StartElement(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * fullname; /* The element name, including namespace prefix */
+ const xmlChar * fullname; /* The element name, including namespace prefix */
int n_fullname;
- xmlChar ** atts; /* An array of name/value attributes pairs, NULL terminated */
+ const xmlChar ** atts; /* An array of name/value attributes pairs, NULL terminated */
int n_atts;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -5115,11 +5140,11 @@ test_xmlSAX2StartElement(void) {
fullname = gen_const_xmlChar_ptr(n_fullname, 1);
atts = gen_const_xmlChar_ptr_ptr(n_atts, 2);
- xmlSAX2StartElement(ctx, (const xmlChar *)fullname, (const xmlChar **)atts);
+ xmlSAX2StartElement(ctx, fullname, atts);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_fullname, (const xmlChar *)fullname, 1);
- des_const_xmlChar_ptr_ptr(n_atts, (const xmlChar **)atts, 2);
+ des_const_xmlChar_ptr(n_fullname, fullname, 1);
+ des_const_xmlChar_ptr_ptr(n_atts, atts, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2StartElement",
@@ -5148,21 +5173,21 @@ test_xmlSAX2StartElementNs(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * localname; /* the local name of the element */
+ const xmlChar * localname; /* the local name of the element */
int n_localname;
- xmlChar * prefix; /* the element namespace prefix if available */
+ const xmlChar * prefix; /* the element namespace prefix if available */
int n_prefix;
- xmlChar * URI; /* the element namespace name if available */
+ const xmlChar * URI; /* the element namespace name if available */
int n_URI;
int nb_namespaces; /* number of namespace definitions on that node */
int n_nb_namespaces;
- xmlChar ** namespaces; /* pointer to the array of prefix/URI pairs namespace definitions */
+ const xmlChar ** namespaces; /* pointer to the array of prefix/URI pairs namespace definitions */
int n_namespaces;
int nb_attributes; /* the number of attributes on that node */
int n_nb_attributes;
int nb_defaulted; /* the number of defaulted attributes. */
int n_nb_defaulted;
- xmlChar ** attributes; /* pointer to the array of (localname/prefix/URI/value/end) attribute values. */
+ const xmlChar ** attributes; /* pointer to the array of (localname/prefix/URI/value/end) attribute values. */
int n_attributes;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -5185,17 +5210,17 @@ test_xmlSAX2StartElementNs(void) {
nb_defaulted = gen_int(n_nb_defaulted, 7);
attributes = gen_const_xmlChar_ptr_ptr(n_attributes, 8);
- xmlSAX2StartElementNs(ctx, (const xmlChar *)localname, (const xmlChar *)prefix, (const xmlChar *)URI, nb_namespaces, (const xmlChar **)namespaces, nb_attributes, nb_defaulted, (const xmlChar **)attributes);
+ xmlSAX2StartElementNs(ctx, localname, prefix, URI, nb_namespaces, namespaces, nb_attributes, nb_defaulted, attributes);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_localname, (const xmlChar *)localname, 1);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 2);
- des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 3);
+ des_const_xmlChar_ptr(n_localname, localname, 1);
+ des_const_xmlChar_ptr(n_prefix, prefix, 2);
+ des_const_xmlChar_ptr(n_URI, URI, 3);
des_int(n_nb_namespaces, nb_namespaces, 4);
- des_const_xmlChar_ptr_ptr(n_namespaces, (const xmlChar **)namespaces, 5);
+ des_const_xmlChar_ptr_ptr(n_namespaces, namespaces, 5);
des_int(n_nb_attributes, nb_attributes, 6);
des_int(n_nb_defaulted, nb_defaulted, 7);
- des_const_xmlChar_ptr_ptr(n_attributes, (const xmlChar **)attributes, 8);
+ des_const_xmlChar_ptr_ptr(n_attributes, attributes, 8);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2StartElementNs",
@@ -5234,13 +5259,13 @@ test_xmlSAX2UnparsedEntityDecl(void) {
int mem_base;
void * ctx; /* the user data (XML parser context) */
int n_ctx;
- xmlChar * name; /* The name of the entity */
+ const xmlChar * name; /* The name of the entity */
int n_name;
- xmlChar * publicId; /* The public ID of the entity */
+ const xmlChar * publicId; /* The public ID of the entity */
int n_publicId;
- xmlChar * systemId; /* The system ID of the entity */
+ const xmlChar * systemId; /* The system ID of the entity */
int n_systemId;
- xmlChar * notationName; /* the name of the notation */
+ const xmlChar * notationName; /* the name of the notation */
int n_notationName;
for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
@@ -5255,13 +5280,13 @@ test_xmlSAX2UnparsedEntityDecl(void) {
systemId = gen_const_xmlChar_ptr(n_systemId, 3);
notationName = gen_const_xmlChar_ptr(n_notationName, 4);
- xmlSAX2UnparsedEntityDecl(ctx, (const xmlChar *)name, (const xmlChar *)publicId, (const xmlChar *)systemId, (const xmlChar *)notationName);
+ xmlSAX2UnparsedEntityDecl(ctx, name, publicId, systemId, notationName);
call_tests++;
des_void_ptr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_publicId, (const xmlChar *)publicId, 2);
- des_const_xmlChar_ptr(n_systemId, (const xmlChar *)systemId, 3);
- des_const_xmlChar_ptr(n_notationName, (const xmlChar *)notationName, 4);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_publicId, publicId, 2);
+ des_const_xmlChar_ptr(n_systemId, systemId, 3);
+ des_const_xmlChar_ptr(n_notationName, notationName, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAX2UnparsedEntityDecl",
@@ -5668,11 +5693,11 @@ test_xmlACatalogAdd(void) {
int ret_val;
xmlCatalogPtr catal; /* a Catalog */
int n_catal;
- xmlChar * type; /* the type of record to add to the catalog */
+ const xmlChar * type; /* the type of record to add to the catalog */
int n_type;
- xmlChar * orig; /* the system, public or prefix to match */
+ const xmlChar * orig; /* the system, public or prefix to match */
int n_orig;
- xmlChar * replace; /* the replacement value for the match */
+ const xmlChar * replace; /* the replacement value for the match */
int n_replace;
for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
@@ -5685,13 +5710,13 @@ test_xmlACatalogAdd(void) {
orig = gen_const_xmlChar_ptr(n_orig, 2);
replace = gen_const_xmlChar_ptr(n_replace, 3);
- ret_val = xmlACatalogAdd(catal, (const xmlChar *)type, (const xmlChar *)orig, (const xmlChar *)replace);
+ ret_val = xmlACatalogAdd(catal, type, orig, replace);
desret_int(ret_val);
call_tests++;
des_xmlCatalogPtr(n_catal, catal, 0);
- des_const_xmlChar_ptr(n_type, (const xmlChar *)type, 1);
- des_const_xmlChar_ptr(n_orig, (const xmlChar *)orig, 2);
- des_const_xmlChar_ptr(n_replace, (const xmlChar *)replace, 3);
+ des_const_xmlChar_ptr(n_type, type, 1);
+ des_const_xmlChar_ptr(n_orig, orig, 2);
+ des_const_xmlChar_ptr(n_replace, replace, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlACatalogAdd",
@@ -5762,7 +5787,7 @@ test_xmlACatalogRemove(void) {
int ret_val;
xmlCatalogPtr catal; /* a Catalog */
int n_catal;
- xmlChar * value; /* the value to remove */
+ const xmlChar * value; /* the value to remove */
int n_value;
for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
@@ -5771,11 +5796,11 @@ test_xmlACatalogRemove(void) {
catal = gen_xmlCatalogPtr(n_catal, 0);
value = gen_const_xmlChar_ptr(n_value, 1);
- ret_val = xmlACatalogRemove(catal, (const xmlChar *)value);
+ ret_val = xmlACatalogRemove(catal, value);
desret_int(ret_val);
call_tests++;
des_xmlCatalogPtr(n_catal, catal, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlACatalogRemove",
@@ -5803,9 +5828,9 @@ test_xmlACatalogResolve(void) {
xmlChar * ret_val;
xmlCatalogPtr catal; /* a Catalog */
int n_catal;
- xmlChar * pubID; /* the public ID string */
+ const xmlChar * pubID; /* the public ID string */
int n_pubID;
- xmlChar * sysID; /* the system ID string */
+ const xmlChar * sysID; /* the system ID string */
int n_sysID;
for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
@@ -5816,12 +5841,12 @@ test_xmlACatalogResolve(void) {
pubID = gen_const_xmlChar_ptr(n_pubID, 1);
sysID = gen_const_xmlChar_ptr(n_sysID, 2);
- ret_val = xmlACatalogResolve(catal, (const xmlChar *)pubID, (const xmlChar *)sysID);
+ ret_val = xmlACatalogResolve(catal, pubID, sysID);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlCatalogPtr(n_catal, catal, 0);
- des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 1);
- des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 2);
+ des_const_xmlChar_ptr(n_pubID, pubID, 1);
+ des_const_xmlChar_ptr(n_sysID, sysID, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlACatalogResolve",
@@ -5851,7 +5876,7 @@ test_xmlACatalogResolvePublic(void) {
xmlChar * ret_val;
xmlCatalogPtr catal; /* a Catalog */
int n_catal;
- xmlChar * pubID; /* the public ID string */
+ const xmlChar * pubID; /* the public ID string */
int n_pubID;
for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
@@ -5860,11 +5885,11 @@ test_xmlACatalogResolvePublic(void) {
catal = gen_xmlCatalogPtr(n_catal, 0);
pubID = gen_const_xmlChar_ptr(n_pubID, 1);
- ret_val = xmlACatalogResolvePublic(catal, (const xmlChar *)pubID);
+ ret_val = xmlACatalogResolvePublic(catal, pubID);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlCatalogPtr(n_catal, catal, 0);
- des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 1);
+ des_const_xmlChar_ptr(n_pubID, pubID, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlACatalogResolvePublic",
@@ -5892,7 +5917,7 @@ test_xmlACatalogResolveSystem(void) {
xmlChar * ret_val;
xmlCatalogPtr catal; /* a Catalog */
int n_catal;
- xmlChar * sysID; /* the system ID string */
+ const xmlChar * sysID; /* the system ID string */
int n_sysID;
for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
@@ -5901,11 +5926,11 @@ test_xmlACatalogResolveSystem(void) {
catal = gen_xmlCatalogPtr(n_catal, 0);
sysID = gen_const_xmlChar_ptr(n_sysID, 1);
- ret_val = xmlACatalogResolveSystem(catal, (const xmlChar *)sysID);
+ ret_val = xmlACatalogResolveSystem(catal, sysID);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlCatalogPtr(n_catal, catal, 0);
- des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 1);
+ des_const_xmlChar_ptr(n_sysID, sysID, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlACatalogResolveSystem",
@@ -5933,7 +5958,7 @@ test_xmlACatalogResolveURI(void) {
xmlChar * ret_val;
xmlCatalogPtr catal; /* a Catalog */
int n_catal;
- xmlChar * URI; /* the URI */
+ const xmlChar * URI; /* the URI */
int n_URI;
for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
@@ -5942,11 +5967,11 @@ test_xmlACatalogResolveURI(void) {
catal = gen_xmlCatalogPtr(n_catal, 0);
URI = gen_const_xmlChar_ptr(n_URI, 1);
- ret_val = xmlACatalogResolveURI(catal, (const xmlChar *)URI);
+ ret_val = xmlACatalogResolveURI(catal, URI);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlCatalogPtr(n_catal, catal, 0);
- des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 1);
+ des_const_xmlChar_ptr(n_URI, URI, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlACatalogResolveURI",
@@ -5972,11 +5997,11 @@ test_xmlCatalogAdd(void) {
#if defined(LIBXML_CATALOG_ENABLED)
int mem_base;
int ret_val;
- xmlChar * type; /* the type of record to add to the catalog */
+ const xmlChar * type; /* the type of record to add to the catalog */
int n_type;
- xmlChar * orig; /* the system, public or prefix to match */
+ const xmlChar * orig; /* the system, public or prefix to match */
int n_orig;
- xmlChar * replace; /* the replacement value for the match */
+ const xmlChar * replace; /* the replacement value for the match */
int n_replace;
for (n_type = 0;n_type < gen_nb_const_xmlChar_ptr;n_type++) {
@@ -5987,12 +6012,12 @@ test_xmlCatalogAdd(void) {
orig = gen_const_xmlChar_ptr(n_orig, 1);
replace = gen_const_xmlChar_ptr(n_replace, 2);
- ret_val = xmlCatalogAdd((const xmlChar *)type, (const xmlChar *)orig, (const xmlChar *)replace);
+ ret_val = xmlCatalogAdd(type, orig, replace);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_type, (const xmlChar *)type, 0);
- des_const_xmlChar_ptr(n_orig, (const xmlChar *)orig, 1);
- des_const_xmlChar_ptr(n_replace, (const xmlChar *)replace, 2);
+ des_const_xmlChar_ptr(n_type, type, 0);
+ des_const_xmlChar_ptr(n_orig, orig, 1);
+ des_const_xmlChar_ptr(n_replace, replace, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCatalogAdd",
@@ -6151,9 +6176,9 @@ test_xmlCatalogLocalResolve(void) {
xmlChar * ret_val;
void * catalogs; /* a document's list of catalogs */
int n_catalogs;
- xmlChar * pubID; /* the public ID string */
+ const xmlChar * pubID; /* the public ID string */
int n_pubID;
- xmlChar * sysID; /* the system ID string */
+ const xmlChar * sysID; /* the system ID string */
int n_sysID;
for (n_catalogs = 0;n_catalogs < gen_nb_void_ptr;n_catalogs++) {
@@ -6164,12 +6189,12 @@ test_xmlCatalogLocalResolve(void) {
pubID = gen_const_xmlChar_ptr(n_pubID, 1);
sysID = gen_const_xmlChar_ptr(n_sysID, 2);
- ret_val = xmlCatalogLocalResolve(catalogs, (const xmlChar *)pubID, (const xmlChar *)sysID);
+ ret_val = xmlCatalogLocalResolve(catalogs, pubID, sysID);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_void_ptr(n_catalogs, catalogs, 0);
- des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 1);
- des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 2);
+ des_const_xmlChar_ptr(n_pubID, pubID, 1);
+ des_const_xmlChar_ptr(n_sysID, sysID, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCatalogLocalResolve",
@@ -6199,7 +6224,7 @@ test_xmlCatalogLocalResolveURI(void) {
xmlChar * ret_val;
void * catalogs; /* a document's list of catalogs */
int n_catalogs;
- xmlChar * URI; /* the URI */
+ const xmlChar * URI; /* the URI */
int n_URI;
for (n_catalogs = 0;n_catalogs < gen_nb_void_ptr;n_catalogs++) {
@@ -6208,11 +6233,11 @@ test_xmlCatalogLocalResolveURI(void) {
catalogs = gen_void_ptr(n_catalogs, 0);
URI = gen_const_xmlChar_ptr(n_URI, 1);
- ret_val = xmlCatalogLocalResolveURI(catalogs, (const xmlChar *)URI);
+ ret_val = xmlCatalogLocalResolveURI(catalogs, URI);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_void_ptr(n_catalogs, catalogs, 0);
- des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 1);
+ des_const_xmlChar_ptr(n_URI, URI, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCatalogLocalResolveURI",
@@ -6237,16 +6262,16 @@ test_xmlCatalogRemove(void) {
#if defined(LIBXML_CATALOG_ENABLED)
int ret_val;
- xmlChar * value; /* the value to remove */
+ const xmlChar * value; /* the value to remove */
int n_value;
for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
value = gen_const_xmlChar_ptr(n_value, 0);
- ret_val = xmlCatalogRemove((const xmlChar *)value);
+ ret_val = xmlCatalogRemove(value);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
xmlResetLastError();
}
function_tests++;
@@ -6262,9 +6287,9 @@ test_xmlCatalogResolve(void) {
#if defined(LIBXML_CATALOG_ENABLED)
xmlChar * ret_val;
- xmlChar * pubID; /* the public ID string */
+ const xmlChar * pubID; /* the public ID string */
int n_pubID;
- xmlChar * sysID; /* the system ID string */
+ const xmlChar * sysID; /* the system ID string */
int n_sysID;
for (n_pubID = 0;n_pubID < gen_nb_const_xmlChar_ptr;n_pubID++) {
@@ -6272,11 +6297,11 @@ test_xmlCatalogResolve(void) {
pubID = gen_const_xmlChar_ptr(n_pubID, 0);
sysID = gen_const_xmlChar_ptr(n_sysID, 1);
- ret_val = xmlCatalogResolve((const xmlChar *)pubID, (const xmlChar *)sysID);
+ ret_val = xmlCatalogResolve(pubID, sysID);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 0);
- des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 1);
+ des_const_xmlChar_ptr(n_pubID, pubID, 0);
+ des_const_xmlChar_ptr(n_sysID, sysID, 1);
xmlResetLastError();
}
}
@@ -6294,17 +6319,17 @@ test_xmlCatalogResolvePublic(void) {
#if defined(LIBXML_CATALOG_ENABLED)
int mem_base;
xmlChar * ret_val;
- xmlChar * pubID; /* the public ID string */
+ const xmlChar * pubID; /* the public ID string */
int n_pubID;
for (n_pubID = 0;n_pubID < gen_nb_const_xmlChar_ptr;n_pubID++) {
mem_base = xmlMemBlocks();
pubID = gen_const_xmlChar_ptr(n_pubID, 0);
- ret_val = xmlCatalogResolvePublic((const xmlChar *)pubID);
+ ret_val = xmlCatalogResolvePublic(pubID);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 0);
+ des_const_xmlChar_ptr(n_pubID, pubID, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCatalogResolvePublic",
@@ -6328,17 +6353,17 @@ test_xmlCatalogResolveSystem(void) {
#if defined(LIBXML_CATALOG_ENABLED)
int mem_base;
xmlChar * ret_val;
- xmlChar * sysID; /* the system ID string */
+ const xmlChar * sysID; /* the system ID string */
int n_sysID;
for (n_sysID = 0;n_sysID < gen_nb_const_xmlChar_ptr;n_sysID++) {
mem_base = xmlMemBlocks();
sysID = gen_const_xmlChar_ptr(n_sysID, 0);
- ret_val = xmlCatalogResolveSystem((const xmlChar *)sysID);
+ ret_val = xmlCatalogResolveSystem(sysID);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 0);
+ des_const_xmlChar_ptr(n_sysID, sysID, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCatalogResolveSystem",
@@ -6362,17 +6387,17 @@ test_xmlCatalogResolveURI(void) {
#if defined(LIBXML_CATALOG_ENABLED)
int mem_base;
xmlChar * ret_val;
- xmlChar * URI; /* the URI */
+ const xmlChar * URI; /* the URI */
int n_URI;
for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
mem_base = xmlMemBlocks();
URI = gen_const_xmlChar_ptr(n_URI, 0);
- ret_val = xmlCatalogResolveURI((const xmlChar *)URI);
+ ret_val = xmlCatalogResolveURI(URI);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
+ des_const_xmlChar_ptr(n_URI, URI, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCatalogResolveURI",
@@ -6554,15 +6579,15 @@ test_xmlLoadCatalogs(void) {
int test_ret = 0;
#if defined(LIBXML_CATALOG_ENABLED)
- char * pathss; /* a list of directories separated by a colon or a space. */
+ const char * pathss; /* a list of directories separated by a colon or a space. */
int n_pathss;
for (n_pathss = 0;n_pathss < gen_nb_const_char_ptr;n_pathss++) {
pathss = gen_const_char_ptr(n_pathss, 0);
- xmlLoadCatalogs((const char *)pathss);
+ xmlLoadCatalogs(pathss);
call_tests++;
- des_const_char_ptr(n_pathss, (const char *)pathss, 0);
+ des_const_char_ptr(n_pathss, pathss, 0);
xmlResetLastError();
}
function_tests++;
@@ -6678,7 +6703,7 @@ test_xmlCharInRange(void) {
int ret_val;
unsigned int val; /* character to be validated */
int n_val;
- xmlChRangeGroup * rptr; /* pointer to range to be used to validate */
+ const xmlChRangeGroup * rptr; /* pointer to range to be used to validate */
int n_rptr;
for (n_val = 0;n_val < gen_nb_unsigned_int;n_val++) {
@@ -6687,11 +6712,11 @@ test_xmlCharInRange(void) {
val = gen_unsigned_int(n_val, 0);
rptr = gen_const_xmlChRangeGroup_ptr(n_rptr, 1);
- ret_val = xmlCharInRange(val, (const xmlChRangeGroup *)rptr);
+ ret_val = xmlCharInRange(val, rptr);
desret_int(ret_val);
call_tests++;
des_unsigned_int(n_val, val, 0);
- des_const_xmlChRangeGroup_ptr(n_rptr, (const xmlChRangeGroup *)rptr, 1);
+ des_const_xmlChRangeGroup_ptr(n_rptr, rptr, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCharInRange",
@@ -7453,7 +7478,7 @@ test_xmlDebugDumpString(void) {
int mem_base;
FILE * output; /* the FILE * for the output */
int n_output;
- xmlChar * str; /* the string */
+ const xmlChar * str; /* the string */
int n_str;
for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
@@ -7462,10 +7487,10 @@ test_xmlDebugDumpString(void) {
output = gen_debug_FILE_ptr(n_output, 0);
str = gen_const_xmlChar_ptr(n_str, 1);
- xmlDebugDumpString(output, (const xmlChar *)str);
+ xmlDebugDumpString(output, str);
call_tests++;
des_debug_FILE_ptr(n_output, output, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlDebugDumpString",
@@ -8277,7 +8302,7 @@ test_xmlDictExists(void) {
const xmlChar * ret_val;
xmlDictPtr dict; /* the dictionary */
int n_dict;
- xmlChar * name; /* the name of the userdata */
+ const xmlChar * name; /* the name of the userdata */
int n_name;
int len; /* the length of the name, if -1 it is recomputed */
int n_len;
@@ -8293,11 +8318,11 @@ test_xmlDictExists(void) {
(len > xmlStrlen(BAD_CAST name)))
len = 0;
- ret_val = xmlDictExists(dict, (const xmlChar *)name, len);
+ ret_val = xmlDictExists(dict, name, len);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
des_xmlDictPtr(n_dict, dict, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -8336,7 +8361,7 @@ test_xmlDictLookup(void) {
const xmlChar * ret_val;
xmlDictPtr dict; /* dictionary */
int n_dict;
- xmlChar * name; /* string key */
+ const xmlChar * name; /* string key */
int n_name;
int len; /* length of the key, if -1 it is recomputed */
int n_len;
@@ -8352,11 +8377,11 @@ test_xmlDictLookup(void) {
(len > xmlStrlen(BAD_CAST name)))
len = 0;
- ret_val = xmlDictLookup(dict, (const xmlChar *)name, len);
+ ret_val = xmlDictLookup(dict, name, len);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
des_xmlDictPtr(n_dict, dict, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -8385,7 +8410,7 @@ test_xmlDictOwns(void) {
int ret_val;
xmlDictPtr dict; /* the dictionary */
int n_dict;
- xmlChar * str; /* the string */
+ const xmlChar * str; /* the string */
int n_str;
for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
@@ -8394,11 +8419,11 @@ test_xmlDictOwns(void) {
dict = gen_xmlDictPtr(n_dict, 0);
str = gen_const_xmlChar_ptr(n_str, 1);
- ret_val = xmlDictOwns(dict, (const xmlChar *)str);
+ ret_val = xmlDictOwns(dict, str);
desret_int(ret_val);
call_tests++;
des_xmlDictPtr(n_dict, dict, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlDictOwns",
@@ -8424,9 +8449,9 @@ test_xmlDictQLookup(void) {
const xmlChar * ret_val;
xmlDictPtr dict; /* the dictionary */
int n_dict;
- xmlChar * prefix; /* the prefix */
+ const xmlChar * prefix; /* the prefix */
int n_prefix;
- xmlChar * name; /* the name */
+ const xmlChar * name; /* the name */
int n_name;
for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
@@ -8437,12 +8462,12 @@ test_xmlDictQLookup(void) {
prefix = gen_const_xmlChar_ptr(n_prefix, 1);
name = gen_const_xmlChar_ptr(n_name, 2);
- ret_val = xmlDictQLookup(dict, (const xmlChar *)prefix, (const xmlChar *)name);
+ ret_val = xmlDictQLookup(dict, prefix, name);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
des_xmlDictPtr(n_dict, dict, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlDictQLookup",
@@ -8596,7 +8621,7 @@ test_UTF8Toisolat1(void) {
int n_out;
int * outlen; /* the length of @out */
int n_outlen;
- unsigned char * in; /* a pointer to an array of UTF-8 chars */
+ const unsigned char * in; /* a pointer to an array of UTF-8 chars */
int n_in;
int * inlen; /* the length of @in */
int n_inlen;
@@ -8611,12 +8636,12 @@ test_UTF8Toisolat1(void) {
in = gen_const_unsigned_char_ptr(n_in, 2);
inlen = gen_int_ptr(n_inlen, 3);
- ret_val = UTF8Toisolat1(out, outlen, (const unsigned char *)in, inlen);
+ ret_val = UTF8Toisolat1(out, outlen, in, inlen);
desret_int(ret_val);
call_tests++;
des_unsigned_char_ptr(n_out, out, 0);
des_int_ptr(n_outlen, outlen, 1);
- des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 2);
+ des_const_unsigned_char_ptr(n_in, in, 2);
des_int_ptr(n_inlen, inlen, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -8651,7 +8676,7 @@ test_isolat1ToUTF8(void) {
int n_out;
int * outlen; /* the length of @out */
int n_outlen;
- unsigned char * in; /* a pointer to an array of ISO Latin 1 chars */
+ const unsigned char * in; /* a pointer to an array of ISO Latin 1 chars */
int n_in;
int * inlen; /* the length of @in */
int n_inlen;
@@ -8666,12 +8691,12 @@ test_isolat1ToUTF8(void) {
in = gen_const_unsigned_char_ptr(n_in, 2);
inlen = gen_int_ptr(n_inlen, 3);
- ret_val = isolat1ToUTF8(out, outlen, (const unsigned char *)in, inlen);
+ ret_val = isolat1ToUTF8(out, outlen, in, inlen);
desret_int(ret_val);
call_tests++;
des_unsigned_char_ptr(n_out, out, 0);
des_int_ptr(n_outlen, outlen, 1);
- des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 2);
+ des_const_unsigned_char_ptr(n_in, in, 2);
des_int_ptr(n_inlen, inlen, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -8699,9 +8724,9 @@ test_xmlAddEncodingAlias(void) {
int test_ret = 0;
int ret_val;
- char * name; /* the encoding name as parsed, in UTF-8 format (ASCII actually) */
+ const char * name; /* the encoding name as parsed, in UTF-8 format (ASCII actually) */
int n_name;
- char * alias; /* the alias name as parsed, in UTF-8 format (ASCII actually) */
+ const char * alias; /* the alias name as parsed, in UTF-8 format (ASCII actually) */
int n_alias;
for (n_name = 0;n_name < gen_nb_const_char_ptr;n_name++) {
@@ -8709,11 +8734,11 @@ test_xmlAddEncodingAlias(void) {
name = gen_const_char_ptr(n_name, 0);
alias = gen_const_char_ptr(n_alias, 1);
- ret_val = xmlAddEncodingAlias((const char *)name, (const char *)alias);
+ ret_val = xmlAddEncodingAlias(name, alias);
desret_int(ret_val);
call_tests++;
- des_const_char_ptr(n_name, (const char *)name, 0);
- des_const_char_ptr(n_alias, (const char *)alias, 1);
+ des_const_char_ptr(n_name, name, 0);
+ des_const_char_ptr(n_alias, alias, 1);
xmlResetLastError();
}
}
@@ -8941,17 +8966,17 @@ test_xmlDelEncodingAlias(void) {
int mem_base;
int ret_val;
- char * alias; /* the alias name as parsed, in UTF-8 format (ASCII actually) */
+ const char * alias; /* the alias name as parsed, in UTF-8 format (ASCII actually) */
int n_alias;
for (n_alias = 0;n_alias < gen_nb_const_char_ptr;n_alias++) {
mem_base = xmlMemBlocks();
alias = gen_const_char_ptr(n_alias, 0);
- ret_val = xmlDelEncodingAlias((const char *)alias);
+ ret_val = xmlDelEncodingAlias(alias);
desret_int(ret_val);
call_tests++;
- des_const_char_ptr(n_alias, (const char *)alias, 0);
+ des_const_char_ptr(n_alias, alias, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlDelEncodingAlias",
@@ -8973,7 +8998,7 @@ test_xmlDetectCharEncoding(void) {
int mem_base;
xmlCharEncoding ret_val;
- unsigned char * in; /* a pointer to the first bytes of the XML entity, must be at least 2 bytes long (at least 4 if encoding is UTF4 variant). */
+ const unsigned char * in; /* a pointer to the first bytes of the XML entity, must be at least 2 bytes long (at least 4 if encoding is UTF4 variant). */
int n_in;
int len; /* pointer to the length of the buffer */
int n_len;
@@ -8984,10 +9009,10 @@ test_xmlDetectCharEncoding(void) {
in = gen_const_unsigned_char_ptr(n_in, 0);
len = gen_int(n_len, 1);
- ret_val = xmlDetectCharEncoding((const unsigned char *)in, len);
+ ret_val = xmlDetectCharEncoding(in, len);
desret_xmlCharEncoding(ret_val);
call_tests++;
- des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 0);
+ des_const_unsigned_char_ptr(n_in, in, 0);
des_int(n_len, len, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -9064,17 +9089,17 @@ test_xmlGetEncodingAlias(void) {
int mem_base;
const char * ret_val;
- char * alias; /* the alias name as parsed, in UTF-8 format (ASCII actually) */
+ const char * alias; /* the alias name as parsed, in UTF-8 format (ASCII actually) */
int n_alias;
for (n_alias = 0;n_alias < gen_nb_const_char_ptr;n_alias++) {
mem_base = xmlMemBlocks();
alias = gen_const_char_ptr(n_alias, 0);
- ret_val = xmlGetEncodingAlias((const char *)alias);
+ ret_val = xmlGetEncodingAlias(alias);
desret_const_char_ptr(ret_val);
call_tests++;
- des_const_char_ptr(n_alias, (const char *)alias, 0);
+ des_const_char_ptr(n_alias, alias, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetEncodingAlias",
@@ -9105,6 +9130,16 @@ test_xmlInitCharEncodingHandlers(void) {
}
+static int
+test_xmlLookupCharEncodingHandler(void) {
+ int test_ret = 0;
+
+
+ /* missing type support */
+ return(test_ret);
+}
+
+
static int
test_xmlNewCharEncodingHandler(void) {
int test_ret = 0;
@@ -9115,23 +9150,33 @@ test_xmlNewCharEncodingHandler(void) {
}
+static int
+test_xmlOpenCharEncodingHandler(void) {
+ int test_ret = 0;
+
+
+ /* missing type support */
+ return(test_ret);
+}
+
+
static int
test_xmlParseCharEncoding(void) {
int test_ret = 0;
int mem_base;
xmlCharEncoding ret_val;
- char * name; /* the encoding name as parsed, in UTF-8 format (ASCII actually) */
+ const char * name; /* the encoding name as parsed, in UTF-8 format (ASCII actually) */
int n_name;
for (n_name = 0;n_name < gen_nb_const_char_ptr;n_name++) {
mem_base = xmlMemBlocks();
name = gen_const_char_ptr(n_name, 0);
- ret_val = xmlParseCharEncoding((const char *)name);
+ ret_val = xmlParseCharEncoding(name);
desret_xmlCharEncoding(ret_val);
call_tests++;
- des_const_char_ptr(n_name, (const char *)name, 0);
+ des_const_char_ptr(n_name, name, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParseCharEncoding",
@@ -9184,7 +9229,7 @@ static int
test_encoding(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing encoding : 16 of 19 functions ...\n");
+ if (quiet == 0) printf("Testing encoding : 16 of 21 functions ...\n");
test_ret += test_UTF8Toisolat1();
test_ret += test_isolat1ToUTF8();
test_ret += test_xmlAddEncodingAlias();
@@ -9201,7 +9246,9 @@ test_encoding(void) {
test_ret += test_xmlGetCharEncodingName();
test_ret += test_xmlGetEncodingAlias();
test_ret += test_xmlInitCharEncodingHandlers();
+ test_ret += test_xmlLookupCharEncodingHandler();
test_ret += test_xmlNewCharEncodingHandler();
+ test_ret += test_xmlOpenCharEncodingHandler();
test_ret += test_xmlParseCharEncoding();
test_ret += test_xmlRegisterCharEncodingHandler();
@@ -9218,15 +9265,15 @@ test_xmlAddDocEntity(void) {
xmlEntityPtr ret_val;
xmlDocPtr doc; /* the document */
int n_doc;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
int type; /* the entity type XML_xxx_yyy_ENTITY */
int n_type;
- xmlChar * ExternalID; /* the entity external ID if available */
+ const xmlChar * ExternalID; /* the entity external ID if available */
int n_ExternalID;
- xmlChar * SystemID; /* the entity system ID if available */
+ const xmlChar * SystemID; /* the entity system ID if available */
int n_SystemID;
- xmlChar * content; /* the entity content */
+ const xmlChar * content; /* the entity content */
int n_content;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -9243,15 +9290,15 @@ test_xmlAddDocEntity(void) {
SystemID = gen_const_xmlChar_ptr(n_SystemID, 4);
content = gen_const_xmlChar_ptr(n_content, 5);
- ret_val = xmlAddDocEntity(doc, (const xmlChar *)name, type, (const xmlChar *)ExternalID, (const xmlChar *)SystemID, (const xmlChar *)content);
+ ret_val = xmlAddDocEntity(doc, name, type, ExternalID, SystemID, content);
desret_xmlEntityPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_int(n_type, type, 2);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 3);
- des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 4);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 5);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 3);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 4);
+ des_const_xmlChar_ptr(n_content, content, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlAddDocEntity",
@@ -9285,15 +9332,15 @@ test_xmlAddDtdEntity(void) {
xmlEntityPtr ret_val;
xmlDocPtr doc; /* the document */
int n_doc;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
int type; /* the entity type XML_xxx_yyy_ENTITY */
int n_type;
- xmlChar * ExternalID; /* the entity external ID if available */
+ const xmlChar * ExternalID; /* the entity external ID if available */
int n_ExternalID;
- xmlChar * SystemID; /* the entity system ID if available */
+ const xmlChar * SystemID; /* the entity system ID if available */
int n_SystemID;
- xmlChar * content; /* the entity content */
+ const xmlChar * content; /* the entity content */
int n_content;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -9310,15 +9357,15 @@ test_xmlAddDtdEntity(void) {
SystemID = gen_const_xmlChar_ptr(n_SystemID, 4);
content = gen_const_xmlChar_ptr(n_content, 5);
- ret_val = xmlAddDtdEntity(doc, (const xmlChar *)name, type, (const xmlChar *)ExternalID, (const xmlChar *)SystemID, (const xmlChar *)content);
+ ret_val = xmlAddDtdEntity(doc, name, type, ExternalID, SystemID, content);
desret_xmlEntityPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_int(n_type, type, 2);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 3);
- des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 4);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 5);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 3);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 4);
+ des_const_xmlChar_ptr(n_content, content, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlAddDtdEntity",
@@ -9344,6 +9391,91 @@ test_xmlAddDtdEntity(void) {
}
+#define gen_nb_xmlEntityPtr_ptr 1
+#define gen_xmlEntityPtr_ptr(no, nr) NULL
+#define des_xmlEntityPtr_ptr(no, val, nr)
+
+static int
+test_xmlAddEntity(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ xmlDocPtr doc; /* the document */
+ int n_doc;
+ int extSubset; /* add to the external or internal subset */
+ int n_extSubset;
+ const xmlChar * name; /* the entity name */
+ int n_name;
+ int type; /* the entity type XML_xxx_yyy_ENTITY */
+ int n_type;
+ const xmlChar * ExternalID; /* the entity external ID if available */
+ int n_ExternalID;
+ const xmlChar * SystemID; /* the entity system ID if available */
+ int n_SystemID;
+ const xmlChar * content; /* the entity content */
+ int n_content;
+ xmlEntityPtr * out; /* pointer to resulting entity (optional) */
+ int n_out;
+
+ for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+ for (n_extSubset = 0;n_extSubset < gen_nb_int;n_extSubset++) {
+ for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+ for (n_type = 0;n_type < gen_nb_int;n_type++) {
+ for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+ for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+ for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+ for (n_out = 0;n_out < gen_nb_xmlEntityPtr_ptr;n_out++) {
+ mem_base = xmlMemBlocks();
+ doc = gen_xmlDocPtr(n_doc, 0);
+ extSubset = gen_int(n_extSubset, 1);
+ name = gen_const_xmlChar_ptr(n_name, 2);
+ type = gen_int(n_type, 3);
+ ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 4);
+ SystemID = gen_const_xmlChar_ptr(n_SystemID, 5);
+ content = gen_const_xmlChar_ptr(n_content, 6);
+ out = gen_xmlEntityPtr_ptr(n_out, 7);
+
+ ret_val = xmlAddEntity(doc, extSubset, name, type, ExternalID, SystemID, content, out);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlDocPtr(n_doc, doc, 0);
+ des_int(n_extSubset, extSubset, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_int(n_type, type, 3);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 4);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 5);
+ des_const_xmlChar_ptr(n_content, content, 6);
+ des_xmlEntityPtr_ptr(n_out, out, 7);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlAddEntity",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_doc);
+ printf(" %d", n_extSubset);
+ printf(" %d", n_name);
+ printf(" %d", n_type);
+ printf(" %d", n_ExternalID);
+ printf(" %d", n_SystemID);
+ printf(" %d", n_content);
+ printf(" %d", n_out);
+ printf("\n");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlCopyEntitiesTable(void) {
int test_ret = 0;
@@ -9458,7 +9590,7 @@ test_xmlEncodeEntitiesReentrant(void) {
xmlChar * ret_val;
xmlDocPtr doc; /* the document containing the string */
int n_doc;
- xmlChar * input; /* A string to convert to XML. */
+ const xmlChar * input; /* A string to convert to XML. */
int n_input;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -9467,11 +9599,11 @@ test_xmlEncodeEntitiesReentrant(void) {
doc = gen_xmlDocPtr(n_doc, 0);
input = gen_const_xmlChar_ptr(n_input, 1);
- ret_val = xmlEncodeEntitiesReentrant(doc, (const xmlChar *)input);
+ ret_val = xmlEncodeEntitiesReentrant(doc, input);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_input, (const xmlChar *)input, 1);
+ des_const_xmlChar_ptr(n_input, input, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlEncodeEntitiesReentrant",
@@ -9499,9 +9631,9 @@ test_xmlEncodeSpecialChars(void) {
int mem_base;
xmlChar * ret_val;
- xmlDoc * doc; /* the document containing the string */
+ const xmlDoc * doc; /* the document containing the string */
int n_doc;
- xmlChar * input; /* A string to convert to XML. */
+ const xmlChar * input; /* A string to convert to XML. */
int n_input;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
@@ -9510,11 +9642,11 @@ test_xmlEncodeSpecialChars(void) {
doc = gen_const_xmlDoc_ptr(n_doc, 0);
input = gen_const_xmlChar_ptr(n_input, 1);
- ret_val = xmlEncodeSpecialChars((const xmlDoc *)doc, (const xmlChar *)input);
+ ret_val = xmlEncodeSpecialChars(doc, input);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
- des_const_xmlChar_ptr(n_input, (const xmlChar *)input, 1);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
+ des_const_xmlChar_ptr(n_input, input, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlEncodeSpecialChars",
@@ -9538,9 +9670,9 @@ test_xmlGetDocEntity(void) {
int mem_base;
xmlEntityPtr ret_val;
- xmlDoc * doc; /* the document referencing the entity */
+ const xmlDoc * doc; /* the document referencing the entity */
int n_doc;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
@@ -9549,11 +9681,11 @@ test_xmlGetDocEntity(void) {
doc = gen_const_xmlDoc_ptr(n_doc, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlGetDocEntity((const xmlDoc *)doc, (const xmlChar *)name);
+ ret_val = xmlGetDocEntity(doc, name);
desret_xmlEntityPtr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetDocEntity",
@@ -9579,7 +9711,7 @@ test_xmlGetDtdEntity(void) {
xmlEntityPtr ret_val;
xmlDocPtr doc; /* the document referencing the entity */
int n_doc;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -9588,11 +9720,11 @@ test_xmlGetDtdEntity(void) {
doc = gen_xmlDocPtr(n_doc, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlGetDtdEntity(doc, (const xmlChar *)name);
+ ret_val = xmlGetDtdEntity(doc, name);
desret_xmlEntityPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetDtdEntity",
@@ -9618,7 +9750,7 @@ test_xmlGetParameterEntity(void) {
xmlEntityPtr ret_val;
xmlDocPtr doc; /* the document referencing the entity */
int n_doc;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -9627,11 +9759,11 @@ test_xmlGetParameterEntity(void) {
doc = gen_xmlDocPtr(n_doc, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlGetParameterEntity(doc, (const xmlChar *)name);
+ ret_val = xmlGetParameterEntity(doc, name);
desret_xmlEntityPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetParameterEntity",
@@ -9655,17 +9787,17 @@ test_xmlGetPredefinedEntity(void) {
int mem_base;
xmlEntityPtr ret_val;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
mem_base = xmlMemBlocks();
name = gen_const_xmlChar_ptr(n_name, 0);
- ret_val = xmlGetPredefinedEntity((const xmlChar *)name);
+ ret_val = xmlGetPredefinedEntity(name);
desret_xmlEntityPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+ des_const_xmlChar_ptr(n_name, name, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetPredefinedEntity",
@@ -9689,15 +9821,15 @@ test_xmlNewEntity(void) {
xmlEntityPtr ret_val;
xmlDocPtr doc; /* the document */
int n_doc;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
int type; /* the entity type XML_xxx_yyy_ENTITY */
int n_type;
- xmlChar * ExternalID; /* the entity external ID if available */
+ const xmlChar * ExternalID; /* the entity external ID if available */
int n_ExternalID;
- xmlChar * SystemID; /* the entity system ID if available */
+ const xmlChar * SystemID; /* the entity system ID if available */
int n_SystemID;
- xmlChar * content; /* the entity content */
+ const xmlChar * content; /* the entity content */
int n_content;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -9714,15 +9846,15 @@ test_xmlNewEntity(void) {
SystemID = gen_const_xmlChar_ptr(n_SystemID, 4);
content = gen_const_xmlChar_ptr(n_content, 5);
- ret_val = xmlNewEntity(doc, (const xmlChar *)name, type, (const xmlChar *)ExternalID, (const xmlChar *)SystemID, (const xmlChar *)content);
+ ret_val = xmlNewEntity(doc, name, type, ExternalID, SystemID, content);
desret_xmlEntityPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_int(n_type, type, 2);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 3);
- des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 4);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 5);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 3);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 4);
+ des_const_xmlChar_ptr(n_content, content, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewEntity",
@@ -9751,9 +9883,10 @@ static int
test_entities(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing entities : 11 of 18 functions ...\n");
+ if (quiet == 0) printf("Testing entities : 12 of 19 functions ...\n");
test_ret += test_xmlAddDocEntity();
test_ret += test_xmlAddDtdEntity();
+ test_ret += test_xmlAddEntity();
test_ret += test_xmlCopyEntitiesTable();
test_ret += test_xmlCreateEntitiesTable();
test_ret += test_xmlDumpEntitiesTable();
@@ -9771,6 +9904,165 @@ test_entities(void) {
return(test_ret);
}
+static int
+test_xmlHashAdd(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ xmlHashTablePtr hash; /* hash table */
+ int n_hash;
+ const xmlChar * key; /* string key */
+ int n_key;
+ void * payload; /* pointer to the payload */
+ int n_payload;
+
+ for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+ for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+ for (n_payload = 0;n_payload < gen_nb_void_ptr;n_payload++) {
+ mem_base = xmlMemBlocks();
+ hash = gen_xmlHashTablePtr(n_hash, 0);
+ key = gen_const_xmlChar_ptr(n_key, 1);
+ payload = gen_void_ptr(n_payload, 2);
+
+ ret_val = xmlHashAdd(hash, key, payload);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlHashTablePtr(n_hash, hash, 0);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_void_ptr(n_payload, payload, 2);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlHashAdd",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_hash);
+ printf(" %d", n_key);
+ printf(" %d", n_payload);
+ printf("\n");
+ }
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
+static int
+test_xmlHashAdd2(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ xmlHashTablePtr hash; /* hash table */
+ int n_hash;
+ const xmlChar * key; /* first string key */
+ int n_key;
+ const xmlChar * key2; /* second string key */
+ int n_key2;
+ void * payload; /* pointer to the payload */
+ int n_payload;
+
+ for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+ for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+ for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+ for (n_payload = 0;n_payload < gen_nb_void_ptr;n_payload++) {
+ mem_base = xmlMemBlocks();
+ hash = gen_xmlHashTablePtr(n_hash, 0);
+ key = gen_const_xmlChar_ptr(n_key, 1);
+ key2 = gen_const_xmlChar_ptr(n_key2, 2);
+ payload = gen_void_ptr(n_payload, 3);
+
+ ret_val = xmlHashAdd2(hash, key, key2, payload);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlHashTablePtr(n_hash, hash, 0);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
+ des_void_ptr(n_payload, payload, 3);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlHashAdd2",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_hash);
+ printf(" %d", n_key);
+ printf(" %d", n_key2);
+ printf(" %d", n_payload);
+ printf("\n");
+ }
+ }
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
+static int
+test_xmlHashAdd3(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ xmlHashTablePtr hash; /* hash table */
+ int n_hash;
+ const xmlChar * key; /* first string key */
+ int n_key;
+ const xmlChar * key2; /* second string key */
+ int n_key2;
+ const xmlChar * key3; /* third string key */
+ int n_key3;
+ void * payload; /* pointer to the payload */
+ int n_payload;
+
+ for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+ for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+ for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+ for (n_key3 = 0;n_key3 < gen_nb_const_xmlChar_ptr;n_key3++) {
+ for (n_payload = 0;n_payload < gen_nb_void_ptr;n_payload++) {
+ mem_base = xmlMemBlocks();
+ hash = gen_xmlHashTablePtr(n_hash, 0);
+ key = gen_const_xmlChar_ptr(n_key, 1);
+ key2 = gen_const_xmlChar_ptr(n_key2, 2);
+ key3 = gen_const_xmlChar_ptr(n_key3, 3);
+ payload = gen_void_ptr(n_payload, 4);
+
+ ret_val = xmlHashAdd3(hash, key, key2, key3, payload);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlHashTablePtr(n_hash, hash, 0);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
+ des_const_xmlChar_ptr(n_key3, key3, 3);
+ des_void_ptr(n_payload, payload, 4);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlHashAdd3",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_hash);
+ printf(" %d", n_key);
+ printf(" %d", n_key2);
+ printf(" %d", n_key3);
+ printf(" %d", n_payload);
+ printf("\n");
+ }
+ }
+ }
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlHashAddEntry(void) {
int test_ret = 0;
@@ -9779,7 +10071,7 @@ test_xmlHashAddEntry(void) {
int ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* string key */
+ const xmlChar * key; /* string key */
int n_key;
void * payload; /* pointer to the payload */
int n_payload;
@@ -9792,11 +10084,11 @@ test_xmlHashAddEntry(void) {
key = gen_const_xmlChar_ptr(n_key, 1);
payload = gen_void_ptr(n_payload, 2);
- ret_val = xmlHashAddEntry(hash, (const xmlChar *)key, payload);
+ ret_val = xmlHashAddEntry(hash, key, payload);
desret_int(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+ des_const_xmlChar_ptr(n_key, key, 1);
des_void_ptr(n_payload, payload, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -9825,9 +10117,9 @@ test_xmlHashAddEntry2(void) {
int ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* first string key */
+ const xmlChar * key; /* first string key */
int n_key;
- xmlChar * key2; /* second string key */
+ const xmlChar * key2; /* second string key */
int n_key2;
void * payload; /* pointer to the payload */
int n_payload;
@@ -9842,12 +10134,12 @@ test_xmlHashAddEntry2(void) {
key2 = gen_const_xmlChar_ptr(n_key2, 2);
payload = gen_void_ptr(n_payload, 3);
- ret_val = xmlHashAddEntry2(hash, (const xmlChar *)key, (const xmlChar *)key2, payload);
+ ret_val = xmlHashAddEntry2(hash, key, key2, payload);
desret_int(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
- des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
des_void_ptr(n_payload, payload, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -9878,11 +10170,11 @@ test_xmlHashAddEntry3(void) {
int ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* first string key */
+ const xmlChar * key; /* first string key */
int n_key;
- xmlChar * key2; /* second string key */
+ const xmlChar * key2; /* second string key */
int n_key2;
- xmlChar * key3; /* third string key */
+ const xmlChar * key3; /* third string key */
int n_key3;
void * payload; /* pointer to the payload */
int n_payload;
@@ -9899,13 +10191,13 @@ test_xmlHashAddEntry3(void) {
key3 = gen_const_xmlChar_ptr(n_key3, 3);
payload = gen_void_ptr(n_payload, 4);
- ret_val = xmlHashAddEntry3(hash, (const xmlChar *)key, (const xmlChar *)key2, (const xmlChar *)key3, payload);
+ ret_val = xmlHashAddEntry3(hash, key, key2, key3, payload);
desret_int(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
- des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
- des_const_xmlChar_ptr(n_key3, (const xmlChar *)key3, 3);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
+ des_const_xmlChar_ptr(n_key3, key3, 3);
des_void_ptr(n_payload, payload, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -9940,6 +10232,16 @@ test_xmlHashCopy(void) {
}
+static int
+test_xmlHashCopySafe(void) {
+ int test_ret = 0;
+
+
+ /* missing type support */
+ return(test_ret);
+}
+
+
static int
test_xmlHashCreate(void) {
int test_ret = 0;
@@ -9967,7 +10269,7 @@ test_xmlHashDefaultDeallocator(void) {
int mem_base;
void * entry; /* hash table entry */
int n_entry;
- xmlChar * key; /* the entry's string key */
+ const xmlChar * key; /* the entry's string key */
int n_key;
for (n_entry = 0;n_entry < gen_nb_void_ptr;n_entry++) {
@@ -9976,10 +10278,10 @@ test_xmlHashDefaultDeallocator(void) {
entry = gen_void_ptr(n_entry, 0);
key = gen_const_xmlChar_ptr(n_key, 1);
- xmlHashDefaultDeallocator(entry, (const xmlChar *)key);
+ xmlHashDefaultDeallocator(entry, key);
call_tests++;
des_void_ptr(n_entry, entry, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+ des_const_xmlChar_ptr(n_key, key, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlHashDefaultDeallocator",
@@ -10005,7 +10307,7 @@ test_xmlHashLookup(void) {
void * ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* string key */
+ const xmlChar * key; /* string key */
int n_key;
for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
@@ -10014,11 +10316,11 @@ test_xmlHashLookup(void) {
hash = gen_xmlHashTablePtr(n_hash, 0);
key = gen_const_xmlChar_ptr(n_key, 1);
- ret_val = xmlHashLookup(hash, (const xmlChar *)key);
+ ret_val = xmlHashLookup(hash, key);
desret_void_ptr(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+ des_const_xmlChar_ptr(n_key, key, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlHashLookup",
@@ -10044,9 +10346,9 @@ test_xmlHashLookup2(void) {
void * ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* first string key */
+ const xmlChar * key; /* first string key */
int n_key;
- xmlChar * key2; /* second string key */
+ const xmlChar * key2; /* second string key */
int n_key2;
for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
@@ -10057,12 +10359,12 @@ test_xmlHashLookup2(void) {
key = gen_const_xmlChar_ptr(n_key, 1);
key2 = gen_const_xmlChar_ptr(n_key2, 2);
- ret_val = xmlHashLookup2(hash, (const xmlChar *)key, (const xmlChar *)key2);
+ ret_val = xmlHashLookup2(hash, key, key2);
desret_void_ptr(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
- des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlHashLookup2",
@@ -10090,11 +10392,11 @@ test_xmlHashLookup3(void) {
void * ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* first string key */
+ const xmlChar * key; /* first string key */
int n_key;
- xmlChar * key2; /* second string key */
+ const xmlChar * key2; /* second string key */
int n_key2;
- xmlChar * key3; /* third string key */
+ const xmlChar * key3; /* third string key */
int n_key3;
for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
@@ -10107,13 +10409,13 @@ test_xmlHashLookup3(void) {
key2 = gen_const_xmlChar_ptr(n_key2, 2);
key3 = gen_const_xmlChar_ptr(n_key3, 3);
- ret_val = xmlHashLookup3(hash, (const xmlChar *)key, (const xmlChar *)key2, (const xmlChar *)key3);
+ ret_val = xmlHashLookup3(hash, key, key2, key3);
desret_void_ptr(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
- des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
- des_const_xmlChar_ptr(n_key3, (const xmlChar *)key3, 3);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
+ des_const_xmlChar_ptr(n_key3, key3, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlHashLookup3",
@@ -10143,9 +10445,9 @@ test_xmlHashQLookup(void) {
void * ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * prefix; /* prefix of the string key */
+ const xmlChar * prefix; /* prefix of the string key */
int n_prefix;
- xmlChar * name; /* local name of the string key */
+ const xmlChar * name; /* local name of the string key */
int n_name;
for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
@@ -10156,12 +10458,12 @@ test_xmlHashQLookup(void) {
prefix = gen_const_xmlChar_ptr(n_prefix, 1);
name = gen_const_xmlChar_ptr(n_name, 2);
- ret_val = xmlHashQLookup(hash, (const xmlChar *)prefix, (const xmlChar *)name);
+ ret_val = xmlHashQLookup(hash, prefix, name);
desret_void_ptr(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlHashQLookup",
@@ -10189,13 +10491,13 @@ test_xmlHashQLookup2(void) {
void * ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * prefix; /* first prefix */
+ const xmlChar * prefix; /* first prefix */
int n_prefix;
- xmlChar * name; /* first local name */
+ const xmlChar * name; /* first local name */
int n_name;
- xmlChar * prefix2; /* second prefix */
+ const xmlChar * prefix2; /* second prefix */
int n_prefix2;
- xmlChar * name2; /* second local name */
+ const xmlChar * name2; /* second local name */
int n_name2;
for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
@@ -10210,14 +10512,14 @@ test_xmlHashQLookup2(void) {
prefix2 = gen_const_xmlChar_ptr(n_prefix2, 3);
name2 = gen_const_xmlChar_ptr(n_name2, 4);
- ret_val = xmlHashQLookup2(hash, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)prefix2, (const xmlChar *)name2);
+ ret_val = xmlHashQLookup2(hash, prefix, name, prefix2, name2);
desret_void_ptr(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_prefix2, (const xmlChar *)prefix2, 3);
- des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 4);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_prefix2, prefix2, 3);
+ des_const_xmlChar_ptr(n_name2, name2, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlHashQLookup2",
@@ -10249,17 +10551,17 @@ test_xmlHashQLookup3(void) {
void * ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * prefix; /* first prefix */
+ const xmlChar * prefix; /* first prefix */
int n_prefix;
- xmlChar * name; /* first local name */
+ const xmlChar * name; /* first local name */
int n_name;
- xmlChar * prefix2; /* second prefix */
+ const xmlChar * prefix2; /* second prefix */
int n_prefix2;
- xmlChar * name2; /* second local name */
+ const xmlChar * name2; /* second local name */
int n_name2;
- xmlChar * prefix3; /* third prefix */
+ const xmlChar * prefix3; /* third prefix */
int n_prefix3;
- xmlChar * name3; /* third local name */
+ const xmlChar * name3; /* third local name */
int n_name3;
for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
@@ -10278,16 +10580,16 @@ test_xmlHashQLookup3(void) {
prefix3 = gen_const_xmlChar_ptr(n_prefix3, 5);
name3 = gen_const_xmlChar_ptr(n_name3, 6);
- ret_val = xmlHashQLookup3(hash, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)prefix2, (const xmlChar *)name2, (const xmlChar *)prefix3, (const xmlChar *)name3);
+ ret_val = xmlHashQLookup3(hash, prefix, name, prefix2, name2, prefix3, name3);
desret_void_ptr(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_prefix2, (const xmlChar *)prefix2, 3);
- des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 4);
- des_const_xmlChar_ptr(n_prefix3, (const xmlChar *)prefix3, 5);
- des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 6);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_prefix2, prefix2, 3);
+ des_const_xmlChar_ptr(n_name2, name2, 4);
+ des_const_xmlChar_ptr(n_prefix3, prefix3, 5);
+ des_const_xmlChar_ptr(n_name3, name3, 6);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlHashQLookup3",
@@ -10323,7 +10625,7 @@ test_xmlHashRemoveEntry(void) {
int ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* string key */
+ const xmlChar * key; /* string key */
int n_key;
xmlHashDeallocator dealloc; /* deallocator function for removed item or NULL */
int n_dealloc;
@@ -10336,11 +10638,11 @@ test_xmlHashRemoveEntry(void) {
key = gen_const_xmlChar_ptr(n_key, 1);
dealloc = gen_xmlHashDeallocator(n_dealloc, 2);
- ret_val = xmlHashRemoveEntry(hash, (const xmlChar *)key, dealloc);
+ ret_val = xmlHashRemoveEntry(hash, key, dealloc);
desret_int(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+ des_const_xmlChar_ptr(n_key, key, 1);
des_xmlHashDeallocator(n_dealloc, dealloc, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -10369,9 +10671,9 @@ test_xmlHashRemoveEntry2(void) {
int ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* first string key */
+ const xmlChar * key; /* first string key */
int n_key;
- xmlChar * key2; /* second string key */
+ const xmlChar * key2; /* second string key */
int n_key2;
xmlHashDeallocator dealloc; /* deallocator function for removed item or NULL */
int n_dealloc;
@@ -10386,12 +10688,12 @@ test_xmlHashRemoveEntry2(void) {
key2 = gen_const_xmlChar_ptr(n_key2, 2);
dealloc = gen_xmlHashDeallocator(n_dealloc, 3);
- ret_val = xmlHashRemoveEntry2(hash, (const xmlChar *)key, (const xmlChar *)key2, dealloc);
+ ret_val = xmlHashRemoveEntry2(hash, key, key2, dealloc);
desret_int(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
- des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
des_xmlHashDeallocator(n_dealloc, dealloc, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -10422,11 +10724,11 @@ test_xmlHashRemoveEntry3(void) {
int ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* first string key */
+ const xmlChar * key; /* first string key */
int n_key;
- xmlChar * key2; /* second string key */
+ const xmlChar * key2; /* second string key */
int n_key2;
- xmlChar * key3; /* third string key */
+ const xmlChar * key3; /* third string key */
int n_key3;
xmlHashDeallocator dealloc; /* deallocator function for removed item or NULL */
int n_dealloc;
@@ -10443,13 +10745,13 @@ test_xmlHashRemoveEntry3(void) {
key3 = gen_const_xmlChar_ptr(n_key3, 3);
dealloc = gen_xmlHashDeallocator(n_dealloc, 4);
- ret_val = xmlHashRemoveEntry3(hash, (const xmlChar *)key, (const xmlChar *)key2, (const xmlChar *)key3, dealloc);
+ ret_val = xmlHashRemoveEntry3(hash, key, key2, key3, dealloc);
desret_int(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
- des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
- des_const_xmlChar_ptr(n_key3, (const xmlChar *)key3, 3);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
+ des_const_xmlChar_ptr(n_key3, key3, 3);
des_xmlHashDeallocator(n_dealloc, dealloc, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -10554,7 +10856,7 @@ test_xmlHashUpdateEntry(void) {
int ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* string key */
+ const xmlChar * key; /* string key */
int n_key;
void * payload; /* pointer to the payload */
int n_payload;
@@ -10571,11 +10873,11 @@ test_xmlHashUpdateEntry(void) {
payload = gen_void_ptr(n_payload, 2);
dealloc = gen_xmlHashDeallocator(n_dealloc, 3);
- ret_val = xmlHashUpdateEntry(hash, (const xmlChar *)key, payload, dealloc);
+ ret_val = xmlHashUpdateEntry(hash, key, payload, dealloc);
desret_int(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+ des_const_xmlChar_ptr(n_key, key, 1);
des_void_ptr(n_payload, payload, 2);
des_xmlHashDeallocator(n_dealloc, dealloc, 3);
xmlResetLastError();
@@ -10607,9 +10909,9 @@ test_xmlHashUpdateEntry2(void) {
int ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* first string key */
+ const xmlChar * key; /* first string key */
int n_key;
- xmlChar * key2; /* second string key */
+ const xmlChar * key2; /* second string key */
int n_key2;
void * payload; /* pointer to the payload */
int n_payload;
@@ -10628,12 +10930,12 @@ test_xmlHashUpdateEntry2(void) {
payload = gen_void_ptr(n_payload, 3);
dealloc = gen_xmlHashDeallocator(n_dealloc, 4);
- ret_val = xmlHashUpdateEntry2(hash, (const xmlChar *)key, (const xmlChar *)key2, payload, dealloc);
+ ret_val = xmlHashUpdateEntry2(hash, key, key2, payload, dealloc);
desret_int(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
- des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
des_void_ptr(n_payload, payload, 3);
des_xmlHashDeallocator(n_dealloc, dealloc, 4);
xmlResetLastError();
@@ -10667,11 +10969,11 @@ test_xmlHashUpdateEntry3(void) {
int ret_val;
xmlHashTablePtr hash; /* hash table */
int n_hash;
- xmlChar * key; /* first string key */
+ const xmlChar * key; /* first string key */
int n_key;
- xmlChar * key2; /* second string key */
+ const xmlChar * key2; /* second string key */
int n_key2;
- xmlChar * key3; /* third string key */
+ const xmlChar * key3; /* third string key */
int n_key3;
void * payload; /* pointer to the payload */
int n_payload;
@@ -10692,13 +10994,13 @@ test_xmlHashUpdateEntry3(void) {
payload = gen_void_ptr(n_payload, 4);
dealloc = gen_xmlHashDeallocator(n_dealloc, 5);
- ret_val = xmlHashUpdateEntry3(hash, (const xmlChar *)key, (const xmlChar *)key2, (const xmlChar *)key3, payload, dealloc);
+ ret_val = xmlHashUpdateEntry3(hash, key, key2, key3, payload, dealloc);
desret_int(ret_val);
call_tests++;
des_xmlHashTablePtr(n_hash, hash, 0);
- des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
- des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
- des_const_xmlChar_ptr(n_key3, (const xmlChar *)key3, 3);
+ des_const_xmlChar_ptr(n_key, key, 1);
+ des_const_xmlChar_ptr(n_key2, key2, 2);
+ des_const_xmlChar_ptr(n_key3, key3, 3);
des_void_ptr(n_payload, payload, 4);
des_xmlHashDeallocator(n_dealloc, dealloc, 5);
xmlResetLastError();
@@ -10729,11 +11031,15 @@ static int
test_hash(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing hash : 17 of 25 functions ...\n");
+ if (quiet == 0) printf("Testing hash : 20 of 29 functions ...\n");
+ test_ret += test_xmlHashAdd();
+ test_ret += test_xmlHashAdd2();
+ test_ret += test_xmlHashAdd3();
test_ret += test_xmlHashAddEntry();
test_ret += test_xmlHashAddEntry2();
test_ret += test_xmlHashAddEntry3();
test_ret += test_xmlHashCopy();
+ test_ret += test_xmlHashCopySafe();
test_ret += test_xmlHashCreate();
test_ret += test_xmlHashCreateDict();
test_ret += test_xmlHashDefaultDeallocator();
@@ -10865,10 +11171,6 @@ test_xmlListClear(void) {
}
-#define gen_nb_const_xmlListPtr 1
-#define gen_const_xmlListPtr(no, nr) NULL
-#define des_const_xmlListPtr(no, val, nr)
-
static int
test_xmlListCopy(void) {
int test_ret = 0;
@@ -10881,16 +11183,16 @@ test_xmlListCopy(void) {
int n_old;
for (n_cur = 0;n_cur < gen_nb_xmlListPtr;n_cur++) {
- for (n_old = 0;n_old < gen_nb_const_xmlListPtr;n_old++) {
+ for (n_old = 0;n_old < gen_nb_xmlListPtr;n_old++) {
mem_base = xmlMemBlocks();
cur = gen_xmlListPtr(n_cur, 0);
- old = gen_const_xmlListPtr(n_old, 1);
+ old = gen_xmlListPtr(n_old, 1);
- ret_val = xmlListCopy(cur, (const xmlListPtr)old);
+ ret_val = xmlListCopy(cur, old);
desret_int(ret_val);
call_tests++;
des_xmlListPtr(n_cur, cur, 0);
- des_const_xmlListPtr(n_old, (const xmlListPtr)old, 1);
+ des_xmlListPtr(n_old, old, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlListCopy",
@@ -12075,6 +12377,29 @@ test_xmlByteConsumed(void) {
}
+static int
+test_xmlCleanupGlobals(void) {
+ int test_ret = 0;
+
+ int mem_base;
+
+ mem_base = xmlMemBlocks();
+
+ xmlCleanupGlobals();
+ call_tests++;
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlCleanupGlobals",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf("\n");
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlClearNodeInfoSeq(void) {
int test_ret = 0;
@@ -12141,17 +12466,17 @@ test_xmlCreateDocParserCtxt(void) {
int mem_base;
xmlParserCtxtPtr ret_val;
- xmlChar * str; /* a pointer to an array of xmlChar */
+ const xmlChar * str; /* a pointer to an array of xmlChar */
int n_str;
for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
mem_base = xmlMemBlocks();
str = gen_const_xmlChar_ptr(n_str, 0);
- ret_val = xmlCreateDocParserCtxt((const xmlChar *)str);
+ ret_val = xmlCreateDocParserCtxt(str);
desret_xmlParserCtxtPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+ des_const_xmlChar_ptr(n_str, str, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCreateDocParserCtxt",
@@ -12174,15 +12499,15 @@ test_xmlCreatePushParserCtxt(void) {
#if defined(LIBXML_PUSH_ENABLED)
int mem_base;
xmlParserCtxtPtr ret_val;
- xmlSAXHandlerPtr sax; /* a SAX handler */
+ xmlSAXHandlerPtr sax; /* a SAX handler (optional) */
int n_sax;
- void * user_data; /* The user data returned on SAX callbacks */
+ void * user_data; /* user data for SAX callbacks (optional) */
int n_user_data;
- char * chunk; /* a pointer to an array of chars */
+ const char * chunk; /* initial chunk (optional, deprecated) */
int n_chunk;
- int size; /* number of chars in the array */
+ int size; /* size of initial chunk in bytes */
int n_size;
- const char * filename; /* an optional file name or URI */
+ const char * filename; /* file name or URI (optional) */
int n_filename;
for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
@@ -12200,12 +12525,12 @@ test_xmlCreatePushParserCtxt(void) {
(size > xmlStrlen(BAD_CAST chunk)))
size = 0;
- ret_val = xmlCreatePushParserCtxt(sax, user_data, (const char *)chunk, size, filename);
+ ret_val = xmlCreatePushParserCtxt(sax, user_data, chunk, size, filename);
desret_xmlParserCtxtPtr(ret_val);
call_tests++;
des_xmlSAXHandlerPtr(n_sax, sax, 0);
des_userdata(n_user_data, user_data, 1);
- des_const_char_ptr(n_chunk, (const char *)chunk, 2);
+ des_const_char_ptr(n_chunk, chunk, 2);
des_int(n_size, size, 3);
des_fileoutput(n_filename, filename, 4);
xmlResetLastError();
@@ -12232,6 +12557,45 @@ test_xmlCreatePushParserCtxt(void) {
}
+static int
+test_xmlCtxtParseDocument(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ xmlDocPtr ret_val;
+ xmlParserCtxtPtr ctxt; /* an XML parser context */
+ int n_ctxt;
+ xmlParserInputPtr input; /* parser input */
+ int n_input;
+
+ for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+ for (n_input = 0;n_input < gen_nb_xmlParserInputPtr;n_input++) {
+ mem_base = xmlMemBlocks();
+ ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+ input = gen_xmlParserInputPtr(n_input, 1);
+
+ ret_val = xmlCtxtParseDocument(ctxt, input);
+ desret_xmlDocPtr(ret_val);
+ call_tests++;
+ des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+ des_xmlParserInputPtr(n_input, input, 1);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlCtxtParseDocument",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_ctxt);
+ printf(" %d", n_input);
+ printf("\n");
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlCtxtReadDoc(void) {
int test_ret = 0;
@@ -12240,11 +12604,11 @@ test_xmlCtxtReadDoc(void) {
xmlDocPtr ret_val;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- xmlChar * str; /* a pointer to a zero terminated string */
+ const xmlChar * str; /* a pointer to a zero terminated string */
int n_str;
- const char * URL; /* the base URL to use for the document */
+ const char * URL; /* base URL (optional) */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -12261,13 +12625,13 @@ test_xmlCtxtReadDoc(void) {
encoding = gen_const_char_ptr(n_encoding, 3);
options = gen_parseroptions(n_options, 4);
- ret_val = xmlCtxtReadDoc(ctxt, (const xmlChar *)str, URL, (const char *)encoding, options);
+ ret_val = xmlCtxtReadDoc(ctxt, str, URL, encoding, options);
desret_xmlDocPtr(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
des_filepath(n_URL, URL, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_const_char_ptr(n_encoding, encoding, 3);
des_parseroptions(n_options, options, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -12302,7 +12666,7 @@ test_xmlCtxtReadFile(void) {
int n_ctxt;
const char * filename; /* a file or URL */
int n_filename;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -12317,12 +12681,12 @@ test_xmlCtxtReadFile(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
options = gen_parseroptions(n_options, 3);
- ret_val = xmlCtxtReadFile(ctxt, filename, (const char *)encoding, options);
+ ret_val = xmlCtxtReadFile(ctxt, filename, encoding, options);
desret_xmlDocPtr(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
des_filepath(n_filename, filename, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_parseroptions(n_options, options, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -12353,13 +12717,13 @@ test_xmlCtxtReadMemory(void) {
xmlDocPtr ret_val;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- char * buffer; /* a pointer to a char array */
+ const char * buffer; /* a pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
- const char * URL; /* the base URL to use for the document */
+ const char * URL; /* base URL (optional) */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -12381,14 +12745,14 @@ test_xmlCtxtReadMemory(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlCtxtReadMemory(ctxt, (const char *)buffer, size, URL, (const char *)encoding, options);
+ ret_val = xmlCtxtReadMemory(ctxt, buffer, size, URL, encoding, options);
desret_xmlDocPtr(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+ des_const_char_ptr(n_buffer, buffer, 1);
des_int(n_size, size, 2);
des_filepath(n_URL, URL, 3);
- des_const_char_ptr(n_encoding, (const char *)encoding, 4);
+ des_const_char_ptr(n_encoding, encoding, 4);
des_parseroptions(n_options, options, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -12453,13 +12817,13 @@ test_xmlCtxtResetPush(void) {
int ret_val;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- char * chunk; /* a pointer to an array of chars */
+ const char * chunk; /* a pointer to an array of chars */
int n_chunk;
int size; /* number of chars in the array */
int n_size;
const char * filename; /* an optional file name or URI */
int n_filename;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding, or NULL */
int n_encoding;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
@@ -12477,14 +12841,14 @@ test_xmlCtxtResetPush(void) {
(size > xmlStrlen(BAD_CAST chunk)))
size = 0;
- ret_val = xmlCtxtResetPush(ctxt, (const char *)chunk, size, filename, (const char *)encoding);
+ ret_val = xmlCtxtResetPush(ctxt, chunk, size, filename, encoding);
desret_int(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_char_ptr(n_chunk, (const char *)chunk, 1);
+ des_const_char_ptr(n_chunk, chunk, 1);
des_int(n_size, size, 2);
des_filepath(n_filename, filename, 3);
- des_const_char_ptr(n_encoding, (const char *)encoding, 4);
+ des_const_char_ptr(n_encoding, encoding, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCtxtResetPush",
@@ -12508,6 +12872,16 @@ test_xmlCtxtResetPush(void) {
}
+static int
+test_xmlCtxtSetErrorHandler(void) {
+ int test_ret = 0;
+
+
+ /* missing type support */
+ return(test_ret);
+}
+
+
static int
test_xmlCtxtSetMaxAmplification(void) {
int test_ret = 0;
@@ -12518,6 +12892,45 @@ test_xmlCtxtSetMaxAmplification(void) {
}
+static int
+test_xmlCtxtSetOptions(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ xmlParserCtxtPtr ctxt; /* an XML parser context */
+ int n_ctxt;
+ int options; /* a bitmask of xmlParserOption values */
+ int n_options;
+
+ for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+ for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+ mem_base = xmlMemBlocks();
+ ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+ options = gen_parseroptions(n_options, 1);
+
+ ret_val = xmlCtxtSetOptions(ctxt, options);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+ des_parseroptions(n_options, options, 1);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlCtxtSetOptions",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_ctxt);
+ printf(" %d", n_options);
+ printf("\n");
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlCtxtUseOptions(void) {
int test_ret = 0;
@@ -12639,6 +13052,29 @@ test_xmlIOParseDTD(void) {
}
+static int
+test_xmlInitGlobals(void) {
+ int test_ret = 0;
+
+ int mem_base;
+
+ mem_base = xmlMemBlocks();
+
+ xmlInitGlobals();
+ call_tests++;
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlInitGlobals",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf("\n");
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlInitNodeInfoSeq(void) {
int test_ret = 0;
@@ -12796,7 +13232,7 @@ test_xmlLoadExternalEntity(void) {
xmlParserInputPtr ret_val;
const char * URL; /* the URL for the entity to load */
int n_URL;
- char * ID; /* the Public ID for the entity to load */
+ const char * ID; /* the Public ID for the entity to load */
int n_ID;
xmlParserCtxtPtr ctxt; /* the context in which the entity is called or NULL */
int n_ctxt;
@@ -12809,11 +13245,11 @@ test_xmlLoadExternalEntity(void) {
ID = gen_const_char_ptr(n_ID, 1);
ctxt = gen_xmlParserCtxtPtr(n_ctxt, 2);
- ret_val = xmlLoadExternalEntity(URL, (const char *)ID, ctxt);
+ ret_val = xmlLoadExternalEntity(URL, ID, ctxt);
desret_xmlParserInputPtr(ret_val);
call_tests++;
des_filepath(n_URL, URL, 0);
- des_const_char_ptr(n_ID, (const char *)ID, 1);
+ des_const_char_ptr(n_ID, ID, 1);
des_xmlParserCtxtPtr(n_ctxt, ctxt, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -12842,25 +13278,25 @@ test_xmlNewIOInputStream(void) {
xmlParserInputPtr ret_val;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- xmlParserInputBufferPtr input; /* an I/O Input */
- int n_input;
+ xmlParserInputBufferPtr buf; /* an input buffer */
+ int n_buf;
xmlCharEncoding enc; /* the charset encoding if known */
int n_enc;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
- for (n_input = 0;n_input < gen_nb_xmlParserInputBufferPtr;n_input++) {
+ for (n_buf = 0;n_buf < gen_nb_xmlParserInputBufferPtr;n_buf++) {
for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
mem_base = xmlMemBlocks();
ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
- input = gen_xmlParserInputBufferPtr(n_input, 1);
+ buf = gen_xmlParserInputBufferPtr(n_buf, 1);
enc = gen_xmlCharEncoding(n_enc, 2);
- ret_val = xmlNewIOInputStream(ctxt, input, enc);
- if (ret_val != NULL) input = NULL;
+ ret_val = xmlNewIOInputStream(ctxt, buf, enc);
+ if (ret_val != NULL) buf = NULL;
desret_xmlParserInputPtr(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_xmlParserInputBufferPtr(n_input, input, 1);
+ des_xmlParserInputBufferPtr(n_buf, buf, 1);
des_xmlCharEncoding(n_enc, enc, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -12868,7 +13304,7 @@ test_xmlNewIOInputStream(void) {
xmlMemBlocks() - mem_base);
test_ret++;
printf(" %d", n_ctxt);
- printf(" %d", n_input);
+ printf(" %d", n_buf);
printf(" %d", n_enc);
printf("\n");
}
@@ -12916,7 +13352,7 @@ test_xmlNewSAXParserCtxt(void) {
int mem_base;
xmlParserCtxtPtr ret_val;
- xmlSAXHandler * sax; /* SAX handler */
+ const xmlSAXHandler * sax; /* SAX handler */
int n_sax;
void * userData; /* user data */
int n_userData;
@@ -12927,10 +13363,10 @@ test_xmlNewSAXParserCtxt(void) {
sax = gen_const_xmlSAXHandler_ptr(n_sax, 0);
userData = gen_userdata(n_userData, 1);
- ret_val = xmlNewSAXParserCtxt((const xmlSAXHandler *)sax, userData);
+ ret_val = xmlNewSAXParserCtxt(sax, userData);
desret_xmlParserCtxtPtr(ret_val);
call_tests++;
- des_const_xmlSAXHandler_ptr(n_sax, (const xmlSAXHandler *)sax, 0);
+ des_const_xmlSAXHandler_ptr(n_sax, sax, 0);
des_userdata(n_userData, userData, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -12969,7 +13405,7 @@ test_xmlParseBalancedChunkMemory(void) {
int n_user_data;
int depth; /* Used for loop detection, use 0 */
int n_depth;
- xmlChar * string; /* the input string in UTF8 or ISO-Latin (zero terminated) */
+ const xmlChar * string; /* the input string in UTF8 or ISO-Latin (zero terminated) */
int n_string;
xmlNodePtr * lst; /* the return value for the set of parsed nodes */
int n_lst;
@@ -12993,14 +13429,14 @@ test_xmlParseBalancedChunkMemory(void) {
#endif
- ret_val = xmlParseBalancedChunkMemory(doc, sax, user_data, depth, (const xmlChar *)string, lst);
+ ret_val = xmlParseBalancedChunkMemory(doc, sax, user_data, depth, string, lst);
desret_int(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
des_xmlSAXHandlerPtr(n_sax, sax, 1);
des_userdata(n_user_data, user_data, 2);
des_int(n_depth, depth, 3);
- des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 4);
+ des_const_xmlChar_ptr(n_string, string, 4);
des_xmlNodePtr_ptr(n_lst, lst, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -13045,10 +13481,10 @@ test_xmlParseBalancedChunkMemoryRecover(void) {
int n_user_data;
int depth; /* Used for loop detection, use 0 */
int n_depth;
- xmlChar * string; /* the input string in UTF8 or ISO-Latin (zero terminated) */
+ const xmlChar * string; /* the input string in UTF8 or ISO-Latin (zero terminated) */
int n_string;
- xmlNodePtr * lst; /* the return value for the set of parsed nodes */
- int n_lst;
+ xmlNodePtr * listOut; /* the return value for the set of parsed nodes */
+ int n_listOut;
int recover; /* return nodes even if the data is broken (use 0) */
int n_recover;
@@ -13057,7 +13493,7 @@ test_xmlParseBalancedChunkMemoryRecover(void) {
for (n_user_data = 0;n_user_data < gen_nb_userdata;n_user_data++) {
for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
for (n_string = 0;n_string < gen_nb_const_xmlChar_ptr;n_string++) {
- for (n_lst = 0;n_lst < gen_nb_xmlNodePtr_ptr;n_lst++) {
+ for (n_listOut = 0;n_listOut < gen_nb_xmlNodePtr_ptr;n_listOut++) {
for (n_recover = 0;n_recover < gen_nb_int;n_recover++) {
mem_base = xmlMemBlocks();
doc = gen_xmlDocPtr(n_doc, 0);
@@ -13065,7 +13501,7 @@ test_xmlParseBalancedChunkMemoryRecover(void) {
user_data = gen_userdata(n_user_data, 2);
depth = gen_int(n_depth, 3);
string = gen_const_xmlChar_ptr(n_string, 4);
- lst = gen_xmlNodePtr_ptr(n_lst, 5);
+ listOut = gen_xmlNodePtr_ptr(n_listOut, 5);
recover = gen_int(n_recover, 6);
#ifdef LIBXML_SAX1_ENABLED
@@ -13073,15 +13509,15 @@ test_xmlParseBalancedChunkMemoryRecover(void) {
#endif
- ret_val = xmlParseBalancedChunkMemoryRecover(doc, sax, user_data, depth, (const xmlChar *)string, lst, recover);
+ ret_val = xmlParseBalancedChunkMemoryRecover(doc, sax, user_data, depth, string, listOut, recover);
desret_int(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
des_xmlSAXHandlerPtr(n_sax, sax, 1);
des_userdata(n_user_data, user_data, 2);
des_int(n_depth, depth, 3);
- des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 4);
- des_xmlNodePtr_ptr(n_lst, lst, 5);
+ des_const_xmlChar_ptr(n_string, string, 4);
+ des_xmlNodePtr_ptr(n_listOut, listOut, 5);
des_int(n_recover, recover, 6);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -13093,7 +13529,7 @@ test_xmlParseBalancedChunkMemoryRecover(void) {
printf(" %d", n_user_data);
printf(" %d", n_depth);
printf(" %d", n_string);
- printf(" %d", n_lst);
+ printf(" %d", n_listOut);
printf(" %d", n_recover);
printf("\n");
}
@@ -13121,9 +13557,9 @@ test_xmlParseChunk(void) {
int ret_val;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- char * chunk; /* an char array */
+ const char * chunk; /* chunk of memory */
int n_chunk;
- int size; /* the size in byte of the chunk */
+ int size; /* size of chunk in bytes */
int n_size;
int terminate; /* last chunk indicator */
int n_terminate;
@@ -13141,12 +13577,12 @@ test_xmlParseChunk(void) {
(size > xmlStrlen(BAD_CAST chunk)))
size = 0;
- ret_val = xmlParseChunk(ctxt, (const char *)chunk, size, terminate);
+ ret_val = xmlParseChunk(ctxt, chunk, size, terminate);
if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}
desret_int(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_char_ptr(n_chunk, (const char *)chunk, 1);
+ des_const_char_ptr(n_chunk, chunk, 1);
des_int(n_size, size, 2);
des_int(n_terminate, terminate, 3);
xmlResetLastError();
@@ -13177,41 +13613,41 @@ test_xmlParseCtxtExternalEntity(void) {
int mem_base;
int ret_val;
- xmlParserCtxtPtr ctx; /* the existing parsing context */
- int n_ctx;
- xmlChar * URL; /* the URL for the entity to load */
+ xmlParserCtxtPtr ctxt; /* the existing parsing context */
+ int n_ctxt;
+ const xmlChar * URL; /* the URL for the entity to load */
int n_URL;
- xmlChar * ID; /* the System ID for the entity to load */
+ const xmlChar * ID; /* the System ID for the entity to load */
int n_ID;
- xmlNodePtr * lst; /* the return value for the set of parsed nodes */
- int n_lst;
+ xmlNodePtr * listOut; /* the return value for the set of parsed nodes */
+ int n_listOut;
- for (n_ctx = 0;n_ctx < gen_nb_xmlParserCtxtPtr;n_ctx++) {
+ for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
for (n_URL = 0;n_URL < gen_nb_const_xmlChar_ptr;n_URL++) {
for (n_ID = 0;n_ID < gen_nb_const_xmlChar_ptr;n_ID++) {
- for (n_lst = 0;n_lst < gen_nb_xmlNodePtr_ptr;n_lst++) {
+ for (n_listOut = 0;n_listOut < gen_nb_xmlNodePtr_ptr;n_listOut++) {
mem_base = xmlMemBlocks();
- ctx = gen_xmlParserCtxtPtr(n_ctx, 0);
+ ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
URL = gen_const_xmlChar_ptr(n_URL, 1);
ID = gen_const_xmlChar_ptr(n_ID, 2);
- lst = gen_xmlNodePtr_ptr(n_lst, 3);
+ listOut = gen_xmlNodePtr_ptr(n_listOut, 3);
- ret_val = xmlParseCtxtExternalEntity(ctx, (const xmlChar *)URL, (const xmlChar *)ID, lst);
+ ret_val = xmlParseCtxtExternalEntity(ctxt, URL, ID, listOut);
desret_int(ret_val);
call_tests++;
- des_xmlParserCtxtPtr(n_ctx, ctx, 0);
- des_const_xmlChar_ptr(n_URL, (const xmlChar *)URL, 1);
- des_const_xmlChar_ptr(n_ID, (const xmlChar *)ID, 2);
- des_xmlNodePtr_ptr(n_lst, lst, 3);
+ des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+ des_const_xmlChar_ptr(n_URL, URL, 1);
+ des_const_xmlChar_ptr(n_ID, ID, 2);
+ des_xmlNodePtr_ptr(n_listOut, listOut, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParseCtxtExternalEntity",
xmlMemBlocks() - mem_base);
test_ret++;
- printf(" %d", n_ctx);
+ printf(" %d", n_ctxt);
printf(" %d", n_URL);
printf(" %d", n_ID);
- printf(" %d", n_lst);
+ printf(" %d", n_listOut);
printf("\n");
}
}
@@ -13232,9 +13668,9 @@ test_xmlParseDTD(void) {
#ifdef LIBXML_VALID_ENABLED
int mem_base;
xmlDtdPtr ret_val;
- xmlChar * ExternalID; /* a NAME* containing the External ID of the DTD */
+ const xmlChar * ExternalID; /* a NAME* containing the External ID of the DTD */
int n_ExternalID;
- xmlChar * SystemID; /* a NAME* containing the URL to the DTD */
+ const xmlChar * SystemID; /* a NAME* containing the URL to the DTD */
int n_SystemID;
for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
@@ -13243,11 +13679,11 @@ test_xmlParseDTD(void) {
ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 0);
SystemID = gen_const_xmlChar_ptr(n_SystemID, 1);
- ret_val = xmlParseDTD((const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+ ret_val = xmlParseDTD(ExternalID, SystemID);
desret_xmlDtdPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 0);
- des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 1);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 0);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParseDTD",
@@ -13275,17 +13711,17 @@ test_xmlParseDoc(void) {
#ifdef LIBXML_SAX1_ENABLED
int mem_base;
xmlDocPtr ret_val;
- xmlChar * cur; /* a pointer to an array of xmlChar */
+ const xmlChar * cur; /* a pointer to an array of xmlChar */
int n_cur;
for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
mem_base = xmlMemBlocks();
cur = gen_const_xmlChar_ptr(n_cur, 0);
- ret_val = xmlParseDoc((const xmlChar *)cur);
+ ret_val = xmlParseDoc(cur);
desret_xmlDocPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+ des_const_xmlChar_ptr(n_cur, cur, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParseDoc",
@@ -13421,12 +13857,12 @@ test_xmlParseExternalEntity(void) {
int n_user_data;
int depth; /* Used for loop detection, use 0 */
int n_depth;
- xmlChar * URL; /* the URL for the entity to load */
+ const xmlChar * URL; /* the URL for the entity to load */
int n_URL;
- xmlChar * ID; /* the System ID for the entity to load */
+ const xmlChar * ID; /* the System ID for the entity to load */
int n_ID;
- xmlNodePtr * lst; /* the return value for the set of parsed nodes */
- int n_lst;
+ xmlNodePtr * list; /* the return value for the set of parsed nodes */
+ int n_list;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
@@ -13434,7 +13870,7 @@ test_xmlParseExternalEntity(void) {
for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
for (n_URL = 0;n_URL < gen_nb_const_xmlChar_ptr;n_URL++) {
for (n_ID = 0;n_ID < gen_nb_const_xmlChar_ptr;n_ID++) {
- for (n_lst = 0;n_lst < gen_nb_xmlNodePtr_ptr;n_lst++) {
+ for (n_list = 0;n_list < gen_nb_xmlNodePtr_ptr;n_list++) {
mem_base = xmlMemBlocks();
doc = gen_xmlDocPtr(n_doc, 0);
sax = gen_xmlSAXHandlerPtr(n_sax, 1);
@@ -13442,18 +13878,18 @@ test_xmlParseExternalEntity(void) {
depth = gen_int(n_depth, 3);
URL = gen_const_xmlChar_ptr(n_URL, 4);
ID = gen_const_xmlChar_ptr(n_ID, 5);
- lst = gen_xmlNodePtr_ptr(n_lst, 6);
+ list = gen_xmlNodePtr_ptr(n_list, 6);
- ret_val = xmlParseExternalEntity(doc, sax, user_data, depth, (const xmlChar *)URL, (const xmlChar *)ID, lst);
+ ret_val = xmlParseExternalEntity(doc, sax, user_data, depth, URL, ID, list);
desret_int(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
des_xmlSAXHandlerPtr(n_sax, sax, 1);
des_userdata(n_user_data, user_data, 2);
des_int(n_depth, depth, 3);
- des_const_xmlChar_ptr(n_URL, (const xmlChar *)URL, 4);
- des_const_xmlChar_ptr(n_ID, (const xmlChar *)ID, 5);
- des_xmlNodePtr_ptr(n_lst, lst, 6);
+ des_const_xmlChar_ptr(n_URL, URL, 4);
+ des_const_xmlChar_ptr(n_ID, ID, 5);
+ des_xmlNodePtr_ptr(n_list, list, 6);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParseExternalEntity",
@@ -13465,7 +13901,7 @@ test_xmlParseExternalEntity(void) {
printf(" %d", n_depth);
printf(" %d", n_URL);
printf(" %d", n_ID);
- printf(" %d", n_lst);
+ printf(" %d", n_list);
printf("\n");
}
}
@@ -13527,7 +13963,7 @@ test_xmlParseInNodeContext(void) {
xmlParserErrors ret_val;
xmlNodePtr node; /* the context node */
int n_node;
- char * data; /* the input string */
+ const char * data; /* the input string */
int n_data;
int datalen; /* the input string length in bytes */
int n_datalen;
@@ -13548,11 +13984,11 @@ test_xmlParseInNodeContext(void) {
options = gen_parseroptions(n_options, 3);
lst = gen_xmlNodePtr_ptr(n_lst, 4);
- ret_val = xmlParseInNodeContext(node, (const char *)data, datalen, options, lst);
+ ret_val = xmlParseInNodeContext(node, data, datalen, options, lst);
desret_xmlParserErrors(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
- des_const_char_ptr(n_data, (const char *)data, 1);
+ des_const_char_ptr(n_data, data, 1);
des_int(n_datalen, datalen, 2);
des_parseroptions(n_options, options, 3);
des_xmlNodePtr_ptr(n_lst, lst, 4);
@@ -13587,7 +14023,7 @@ test_xmlParseMemory(void) {
#ifdef LIBXML_SAX1_ENABLED
int mem_base;
xmlDocPtr ret_val;
- char * buffer; /* an pointer to a char array */
+ const char * buffer; /* an pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
@@ -13601,10 +14037,10 @@ test_xmlParseMemory(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlParseMemory((const char *)buffer, size);
+ ret_val = xmlParseMemory(buffer, size);
desret_xmlDocPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+ des_const_char_ptr(n_buffer, buffer, 0);
des_int(n_size, size, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -13625,9 +14061,9 @@ test_xmlParseMemory(void) {
}
-#define gen_nb_const_xmlParserNodeInfoPtr 1
-#define gen_const_xmlParserNodeInfoPtr(no, nr) NULL
-#define des_const_xmlParserNodeInfoPtr(no, val, nr)
+#define gen_nb_xmlParserNodeInfoPtr 1
+#define gen_xmlParserNodeInfoPtr(no, nr) NULL
+#define des_xmlParserNodeInfoPtr(no, val, nr)
static int
test_xmlParserAddNodeInfo(void) {
@@ -13640,15 +14076,15 @@ test_xmlParserAddNodeInfo(void) {
int n_info;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
- for (n_info = 0;n_info < gen_nb_const_xmlParserNodeInfoPtr;n_info++) {
+ for (n_info = 0;n_info < gen_nb_xmlParserNodeInfoPtr;n_info++) {
mem_base = xmlMemBlocks();
ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
- info = gen_const_xmlParserNodeInfoPtr(n_info, 1);
+ info = gen_xmlParserNodeInfoPtr(n_info, 1);
- xmlParserAddNodeInfo(ctxt, (const xmlParserNodeInfoPtr)info);
+ xmlParserAddNodeInfo(ctxt, info);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlParserNodeInfoPtr(n_info, (const xmlParserNodeInfoPtr)info, 1);
+ des_xmlParserNodeInfoPtr(n_info, info, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParserAddNodeInfo",
@@ -13666,14 +14102,6 @@ test_xmlParserAddNodeInfo(void) {
}
-#define gen_nb_const_xmlParserCtxtPtr 1
-#define gen_const_xmlParserCtxtPtr(no, nr) NULL
-#define des_const_xmlParserCtxtPtr(no, val, nr)
-
-#define gen_nb_const_xmlNodePtr 1
-#define gen_const_xmlNodePtr(no, nr) NULL
-#define des_const_xmlNodePtr(no, val, nr)
-
static int
test_xmlParserFindNodeInfo(void) {
int test_ret = 0;
@@ -13685,17 +14113,17 @@ test_xmlParserFindNodeInfo(void) {
xmlNodePtr node; /* an XML node within the tree */
int n_node;
- for (n_ctx = 0;n_ctx < gen_nb_const_xmlParserCtxtPtr;n_ctx++) {
- for (n_node = 0;n_node < gen_nb_const_xmlNodePtr;n_node++) {
+ for (n_ctx = 0;n_ctx < gen_nb_xmlParserCtxtPtr;n_ctx++) {
+ for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
mem_base = xmlMemBlocks();
- ctx = gen_const_xmlParserCtxtPtr(n_ctx, 0);
- node = gen_const_xmlNodePtr(n_node, 1);
+ ctx = gen_xmlParserCtxtPtr(n_ctx, 0);
+ node = gen_xmlNodePtr(n_node, 1);
- ret_val = xmlParserFindNodeInfo((const xmlParserCtxtPtr)ctx, (const xmlNodePtr)node);
+ ret_val = xmlParserFindNodeInfo(ctx, node);
desret_const_xmlParserNodeInfo_ptr(ret_val);
call_tests++;
- des_const_xmlParserCtxtPtr(n_ctx, (const xmlParserCtxtPtr)ctx, 0);
- des_const_xmlNodePtr(n_node, (const xmlNodePtr)node, 1);
+ des_xmlParserCtxtPtr(n_ctx, ctx, 0);
+ des_xmlNodePtr(n_node, node, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParserFindNodeInfo",
@@ -13713,10 +14141,6 @@ test_xmlParserFindNodeInfo(void) {
}
-#define gen_nb_const_xmlParserNodeInfoSeqPtr 1
-#define gen_const_xmlParserNodeInfoSeqPtr(no, nr) NULL
-#define des_const_xmlParserNodeInfoSeqPtr(no, val, nr)
-
static int
test_xmlParserFindNodeInfoIndex(void) {
int test_ret = 0;
@@ -13728,17 +14152,17 @@ test_xmlParserFindNodeInfoIndex(void) {
xmlNodePtr node; /* an XML node pointer */
int n_node;
- for (n_seq = 0;n_seq < gen_nb_const_xmlParserNodeInfoSeqPtr;n_seq++) {
- for (n_node = 0;n_node < gen_nb_const_xmlNodePtr;n_node++) {
+ for (n_seq = 0;n_seq < gen_nb_xmlParserNodeInfoSeqPtr;n_seq++) {
+ for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
mem_base = xmlMemBlocks();
- seq = gen_const_xmlParserNodeInfoSeqPtr(n_seq, 0);
- node = gen_const_xmlNodePtr(n_node, 1);
+ seq = gen_xmlParserNodeInfoSeqPtr(n_seq, 0);
+ node = gen_xmlNodePtr(n_node, 1);
- ret_val = xmlParserFindNodeInfoIndex((const xmlParserNodeInfoSeqPtr)seq, (const xmlNodePtr)node);
+ ret_val = xmlParserFindNodeInfoIndex(seq, node);
desret_unsigned_long(ret_val);
call_tests++;
- des_const_xmlParserNodeInfoSeqPtr(n_seq, (const xmlParserNodeInfoSeqPtr)seq, 0);
- des_const_xmlNodePtr(n_node, (const xmlNodePtr)node, 1);
+ des_xmlParserNodeInfoSeqPtr(n_seq, seq, 0);
+ des_xmlNodePtr(n_node, node, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParserFindNodeInfoIndex",
@@ -13756,10 +14180,6 @@ test_xmlParserFindNodeInfoIndex(void) {
}
-#define gen_nb_xmlParserInputPtr 1
-#define gen_xmlParserInputPtr(no, nr) NULL
-#define des_xmlParserInputPtr(no, val, nr)
-
static int
test_xmlParserInputGrow(void) {
int test_ret = 0;
@@ -13876,11 +14296,11 @@ test_xmlReadDoc(void) {
int mem_base;
xmlDocPtr ret_val;
- xmlChar * cur; /* a pointer to a zero terminated string */
+ const xmlChar * cur; /* a pointer to a zero terminated string */
int n_cur;
- const char * URL; /* the base URL to use for the document */
+ const char * URL; /* base URL (optional) */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -13895,12 +14315,12 @@ test_xmlReadDoc(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
options = gen_parseroptions(n_options, 3);
- ret_val = xmlReadDoc((const xmlChar *)cur, URL, (const char *)encoding, options);
+ ret_val = xmlReadDoc(cur, URL, encoding, options);
desret_xmlDocPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+ des_const_xmlChar_ptr(n_cur, cur, 0);
des_filepath(n_URL, URL, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_parseroptions(n_options, options, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -13931,7 +14351,7 @@ test_xmlReadFile(void) {
xmlDocPtr ret_val;
const char * filename; /* a file or URL */
int n_filename;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -13944,11 +14364,11 @@ test_xmlReadFile(void) {
encoding = gen_const_char_ptr(n_encoding, 1);
options = gen_parseroptions(n_options, 2);
- ret_val = xmlReadFile(filename, (const char *)encoding, options);
+ ret_val = xmlReadFile(filename, encoding, options);
desret_xmlDocPtr(ret_val);
call_tests++;
des_filepath(n_filename, filename, 0);
- des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+ des_const_char_ptr(n_encoding, encoding, 1);
des_parseroptions(n_options, options, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -13975,39 +14395,39 @@ test_xmlReadMemory(void) {
int mem_base;
xmlDocPtr ret_val;
- char * buffer; /* a pointer to a char array */
+ const char * buffer; /* a pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
- const char * URL; /* the base URL to use for the document */
- int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * url; /* base URL (optional) */
+ int n_url;
+ const char * encoding; /* the document encoding (optional) */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
for (n_size = 0;n_size < gen_nb_int;n_size++) {
- for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+ for (n_url = 0;n_url < gen_nb_filepath;n_url++) {
for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
mem_base = xmlMemBlocks();
buffer = gen_const_char_ptr(n_buffer, 0);
size = gen_int(n_size, 1);
- URL = gen_filepath(n_URL, 2);
+ url = gen_filepath(n_url, 2);
encoding = gen_const_char_ptr(n_encoding, 3);
options = gen_parseroptions(n_options, 4);
if ((buffer != NULL) &&
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlReadMemory((const char *)buffer, size, URL, (const char *)encoding, options);
+ ret_val = xmlReadMemory(buffer, size, url, encoding, options);
desret_xmlDocPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+ des_const_char_ptr(n_buffer, buffer, 0);
des_int(n_size, size, 1);
- des_filepath(n_URL, URL, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_filepath(n_url, url, 2);
+ des_const_char_ptr(n_encoding, encoding, 3);
des_parseroptions(n_options, options, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -14016,7 +14436,7 @@ test_xmlReadMemory(void) {
test_ret++;
printf(" %d", n_buffer);
printf(" %d", n_size);
- printf(" %d", n_URL);
+ printf(" %d", n_url);
printf(" %d", n_encoding);
printf(" %d", n_options);
printf("\n");
@@ -14040,17 +14460,17 @@ test_xmlRecoverDoc(void) {
#ifdef LIBXML_SAX1_ENABLED
int mem_base;
xmlDocPtr ret_val;
- xmlChar * cur; /* a pointer to an array of xmlChar */
+ const xmlChar * cur; /* a pointer to an array of xmlChar */
int n_cur;
for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
mem_base = xmlMemBlocks();
cur = gen_const_xmlChar_ptr(n_cur, 0);
- ret_val = xmlRecoverDoc((const xmlChar *)cur);
+ ret_val = xmlRecoverDoc(cur);
desret_xmlDocPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+ des_const_xmlChar_ptr(n_cur, cur, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlRecoverDoc",
@@ -14112,7 +14532,7 @@ test_xmlRecoverMemory(void) {
#ifdef LIBXML_SAX1_ENABLED
int mem_base;
xmlDocPtr ret_val;
- char * buffer; /* an pointer to a char array */
+ const char * buffer; /* an pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
@@ -14126,10 +14546,10 @@ test_xmlRecoverMemory(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlRecoverMemory((const char *)buffer, size);
+ ret_val = xmlRecoverMemory(buffer, size);
desret_xmlDocPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+ des_const_char_ptr(n_buffer, buffer, 0);
des_int(n_size, size, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -14160,9 +14580,9 @@ test_xmlSAXParseDTD(void) {
xmlDtdPtr ret_val;
xmlSAXHandlerPtr sax; /* the SAX handler block */
int n_sax;
- xmlChar * ExternalID; /* a NAME* containing the External ID of the DTD */
+ const xmlChar * ExternalID; /* a NAME* containing the External ID of the DTD */
int n_ExternalID;
- xmlChar * SystemID; /* a NAME* containing the URL to the DTD */
+ const xmlChar * SystemID; /* a NAME* containing the URL to the DTD */
int n_SystemID;
for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
@@ -14173,12 +14593,12 @@ test_xmlSAXParseDTD(void) {
ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 1);
SystemID = gen_const_xmlChar_ptr(n_SystemID, 2);
- ret_val = xmlSAXParseDTD(sax, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+ ret_val = xmlSAXParseDTD(sax, ExternalID, SystemID);
desret_xmlDtdPtr(ret_val);
call_tests++;
des_xmlSAXHandlerPtr(n_sax, sax, 0);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 1);
- des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 2);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 1);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSAXParseDTD",
@@ -14210,7 +14630,7 @@ test_xmlSAXParseDoc(void) {
xmlDocPtr ret_val;
xmlSAXHandlerPtr sax; /* the SAX handler block */
int n_sax;
- xmlChar * cur; /* a pointer to an array of xmlChar */
+ const xmlChar * cur; /* a pointer to an array of xmlChar */
int n_cur;
int recovery; /* work in recovery mode, i.e. tries to read no Well Formed documents */
int n_recovery;
@@ -14223,11 +14643,11 @@ test_xmlSAXParseDoc(void) {
cur = gen_const_xmlChar_ptr(n_cur, 1);
recovery = gen_int(n_recovery, 2);
- ret_val = xmlSAXParseDoc(sax, (const xmlChar *)cur, recovery);
+ ret_val = xmlSAXParseDoc(sax, cur, recovery);
desret_xmlDocPtr(ret_val);
call_tests++;
des_xmlSAXHandlerPtr(n_sax, sax, 0);
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+ des_const_xmlChar_ptr(n_cur, cur, 1);
des_int(n_recovery, recovery, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -14410,7 +14830,7 @@ test_xmlSAXParseMemory(void) {
xmlDocPtr ret_val;
xmlSAXHandlerPtr sax; /* the SAX handler block */
int n_sax;
- char * buffer; /* an pointer to a char array */
+ const char * buffer; /* an pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
@@ -14430,11 +14850,11 @@ test_xmlSAXParseMemory(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlSAXParseMemory(sax, (const char *)buffer, size, recovery);
+ ret_val = xmlSAXParseMemory(sax, buffer, size, recovery);
desret_xmlDocPtr(ret_val);
call_tests++;
des_xmlSAXHandlerPtr(n_sax, sax, 0);
- des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+ des_const_char_ptr(n_buffer, buffer, 1);
des_int(n_size, size, 2);
des_int(n_recovery, recovery, 3);
xmlResetLastError();
@@ -14470,7 +14890,7 @@ test_xmlSAXParseMemoryWithData(void) {
xmlDocPtr ret_val;
xmlSAXHandlerPtr sax; /* the SAX handler block */
int n_sax;
- char * buffer; /* an pointer to a char array */
+ const char * buffer; /* an pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
@@ -14494,11 +14914,11 @@ test_xmlSAXParseMemoryWithData(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlSAXParseMemoryWithData(sax, (const char *)buffer, size, recovery, data);
+ ret_val = xmlSAXParseMemoryWithData(sax, buffer, size, recovery, data);
desret_xmlDocPtr(ret_val);
call_tests++;
des_xmlSAXHandlerPtr(n_sax, sax, 0);
- des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+ des_const_char_ptr(n_buffer, buffer, 1);
des_int(n_size, size, 2);
des_int(n_recovery, recovery, 3);
des_userdata(n_data, data, 4);
@@ -14594,7 +15014,7 @@ test_xmlSAXUserParseMemory(void) {
int n_sax;
void * user_data; /* The user data returned on SAX callbacks */
int n_user_data;
- char * buffer; /* an in-memory XML document input */
+ const char * buffer; /* an in-memory XML document input */
int n_buffer;
int size; /* the length of the XML document in bytes */
int n_size;
@@ -14617,12 +15037,12 @@ test_xmlSAXUserParseMemory(void) {
#endif
- ret_val = xmlSAXUserParseMemory(sax, user_data, (const char *)buffer, size);
+ ret_val = xmlSAXUserParseMemory(sax, user_data, buffer, size);
desret_int(ret_val);
call_tests++;
des_xmlSAXHandlerPtr(n_sax, sax, 0);
des_userdata(n_user_data, user_data, 1);
- des_const_char_ptr(n_buffer, (const char *)buffer, 2);
+ des_const_char_ptr(n_buffer, buffer, 2);
des_int(n_size, size, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -14666,7 +15086,7 @@ test_xmlSetupParserForBuffer(void) {
int mem_base;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- xmlChar * buffer; /* a xmlChar * buffer */
+ const xmlChar * buffer; /* a xmlChar * buffer */
int n_buffer;
const char * filename; /* a file name */
int n_filename;
@@ -14679,10 +15099,10 @@ test_xmlSetupParserForBuffer(void) {
buffer = gen_const_xmlChar_ptr(n_buffer, 1);
filename = gen_filepath(n_filename, 2);
- xmlSetupParserForBuffer(ctxt, (const xmlChar *)buffer, filename);
+ xmlSetupParserForBuffer(ctxt, buffer, filename);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_buffer, (const xmlChar *)buffer, 1);
+ des_const_xmlChar_ptr(n_buffer, buffer, 1);
des_filepath(n_filename, filename, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -15028,22 +15448,27 @@ static int
test_parser(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing parser : 67 of 80 functions ...\n");
+ if (quiet == 0) printf("Testing parser : 71 of 85 functions ...\n");
test_ret += test_xmlByteConsumed();
+ test_ret += test_xmlCleanupGlobals();
test_ret += test_xmlClearNodeInfoSeq();
test_ret += test_xmlClearParserCtxt();
test_ret += test_xmlCreateDocParserCtxt();
test_ret += test_xmlCreatePushParserCtxt();
+ test_ret += test_xmlCtxtParseDocument();
test_ret += test_xmlCtxtReadDoc();
test_ret += test_xmlCtxtReadFile();
test_ret += test_xmlCtxtReadMemory();
test_ret += test_xmlCtxtReset();
test_ret += test_xmlCtxtResetPush();
+ test_ret += test_xmlCtxtSetErrorHandler();
test_ret += test_xmlCtxtSetMaxAmplification();
+ test_ret += test_xmlCtxtSetOptions();
test_ret += test_xmlCtxtUseOptions();
test_ret += test_xmlGetExternalEntityLoader();
test_ret += test_xmlHasFeature();
test_ret += test_xmlIOParseDTD();
+ test_ret += test_xmlInitGlobals();
test_ret += test_xmlInitNodeInfoSeq();
test_ret += test_xmlInitParser();
test_ret += test_xmlInitParserCtxt();
@@ -15216,7 +15641,7 @@ test_namePush(void) {
int ret_val;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- xmlChar * value; /* the element name */
+ const xmlChar * value; /* the element name */
int n_value;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
@@ -15225,11 +15650,11 @@ test_namePush(void) {
ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
value = gen_const_xmlChar_ptr(n_value, 1);
- ret_val = namePush(ctxt, (const xmlChar *)value);
+ ret_val = namePush(ctxt, value);
desret_int(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in namePush",
@@ -15324,17 +15749,17 @@ test_xmlCheckLanguageID(void) {
int mem_base;
int ret_val;
- xmlChar * lang; /* pointer to the string value */
+ const xmlChar * lang; /* pointer to the string value */
int n_lang;
for (n_lang = 0;n_lang < gen_nb_const_xmlChar_ptr;n_lang++) {
mem_base = xmlMemBlocks();
lang = gen_const_xmlChar_ptr(n_lang, 0);
- ret_val = xmlCheckLanguageID((const xmlChar *)lang);
+ ret_val = xmlCheckLanguageID(lang);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_lang, (const xmlChar *)lang, 0);
+ des_const_xmlChar_ptr(n_lang, lang, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCheckLanguageID",
@@ -15441,11 +15866,11 @@ test_xmlCreateEntityParserCtxt(void) {
int mem_base;
xmlParserCtxtPtr ret_val;
- xmlChar * URL; /* the entity URL */
+ const xmlChar * URL; /* the entity URL */
int n_URL;
- xmlChar * ID; /* the entity PUBLIC ID */
+ const xmlChar * ID; /* the entity PUBLIC ID */
int n_ID;
- xmlChar * base; /* a possible base for the target URI */
+ const xmlChar * base; /* a possible base for the target URI */
int n_base;
for (n_URL = 0;n_URL < gen_nb_const_xmlChar_ptr;n_URL++) {
@@ -15456,12 +15881,12 @@ test_xmlCreateEntityParserCtxt(void) {
ID = gen_const_xmlChar_ptr(n_ID, 1);
base = gen_const_xmlChar_ptr(n_base, 2);
- ret_val = xmlCreateEntityParserCtxt((const xmlChar *)URL, (const xmlChar *)ID, (const xmlChar *)base);
+ ret_val = xmlCreateEntityParserCtxt(URL, ID, base);
desret_xmlParserCtxtPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_URL, (const xmlChar *)URL, 0);
- des_const_xmlChar_ptr(n_ID, (const xmlChar *)ID, 1);
- des_const_xmlChar_ptr(n_base, (const xmlChar *)base, 2);
+ des_const_xmlChar_ptr(n_URL, URL, 0);
+ des_const_xmlChar_ptr(n_ID, ID, 1);
+ des_const_xmlChar_ptr(n_base, base, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCreateEntityParserCtxt",
@@ -15519,7 +15944,7 @@ test_xmlCreateMemoryParserCtxt(void) {
int mem_base;
xmlParserCtxtPtr ret_val;
- char * buffer; /* a pointer to a char array */
+ const char * buffer; /* a pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
@@ -15533,10 +15958,10 @@ test_xmlCreateMemoryParserCtxt(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlCreateMemoryParserCtxt((const char *)buffer, size);
+ ret_val = xmlCreateMemoryParserCtxt(buffer, size);
desret_xmlParserCtxtPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+ des_const_char_ptr(n_buffer, buffer, 0);
des_int(n_size, size, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -15594,6 +16019,36 @@ test_xmlCreateURLParserCtxt(void) {
}
+static int
+test_xmlCtxtErrMemory(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ xmlParserCtxtPtr ctxt; /* an XML parser context */
+ int n_ctxt;
+
+ for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+ mem_base = xmlMemBlocks();
+ ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+ xmlCtxtErrMemory(ctxt);
+ call_tests++;
+ des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlCtxtErrMemory",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_ctxt);
+ printf("\n");
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlCurrentChar(void) {
int test_ret = 0;
@@ -15673,27 +16128,27 @@ test_xmlNewEntityInputStream(void) {
xmlParserInputPtr ret_val;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- xmlEntityPtr entity; /* an Entity pointer */
- int n_entity;
+ xmlEntityPtr ent; /* an Entity pointer */
+ int n_ent;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
- for (n_entity = 0;n_entity < gen_nb_xmlEntityPtr;n_entity++) {
+ for (n_ent = 0;n_ent < gen_nb_xmlEntityPtr;n_ent++) {
mem_base = xmlMemBlocks();
ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
- entity = gen_xmlEntityPtr(n_entity, 1);
+ ent = gen_xmlEntityPtr(n_ent, 1);
- ret_val = xmlNewEntityInputStream(ctxt, entity);
+ ret_val = xmlNewEntityInputStream(ctxt, ent);
desret_xmlParserInputPtr(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_xmlEntityPtr(n_entity, entity, 1);
+ des_xmlEntityPtr(n_ent, ent, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewEntityInputStream",
xmlMemBlocks() - mem_base);
test_ret++;
printf(" %d", n_ctxt);
- printf(" %d", n_entity);
+ printf(" %d", n_ent);
printf("\n");
}
}
@@ -15783,7 +16238,7 @@ test_xmlNewStringInputStream(void) {
xmlParserInputPtr ret_val;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- xmlChar * buffer; /* an memory buffer */
+ const xmlChar * buffer; /* an memory buffer */
int n_buffer;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
@@ -15792,11 +16247,11 @@ test_xmlNewStringInputStream(void) {
ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
buffer = gen_const_xmlChar_ptr(n_buffer, 1);
- ret_val = xmlNewStringInputStream(ctxt, (const xmlChar *)buffer);
+ ret_val = xmlNewStringInputStream(ctxt, buffer);
desret_xmlParserInputPtr(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_buffer, (const xmlChar *)buffer, 1);
+ des_const_xmlChar_ptr(n_buffer, buffer, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewStringInputStream",
@@ -15963,25 +16418,25 @@ test_xmlSplitQName(void) {
xmlChar * ret_val;
xmlParserCtxtPtr ctxt; /* an XML parser context */
int n_ctxt;
- xmlChar * name; /* an XML parser context */
+ const xmlChar * name; /* an XML parser context */
int n_name;
- xmlChar ** prefix; /* a xmlChar ** */
- int n_prefix;
+ xmlChar ** prefixOut; /* a xmlChar ** */
+ int n_prefixOut;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
- for (n_prefix = 0;n_prefix < gen_nb_xmlChar_ptr_ptr;n_prefix++) {
+ for (n_prefixOut = 0;n_prefixOut < gen_nb_xmlChar_ptr_ptr;n_prefixOut++) {
mem_base = xmlMemBlocks();
ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- prefix = gen_xmlChar_ptr_ptr(n_prefix, 2);
+ prefixOut = gen_xmlChar_ptr_ptr(n_prefixOut, 2);
- ret_val = xmlSplitQName(ctxt, (const xmlChar *)name, prefix);
+ ret_val = xmlSplitQName(ctxt, name, prefixOut);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_xmlChar_ptr_ptr(n_prefix, prefix, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_xmlChar_ptr_ptr(n_prefixOut, prefixOut, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSplitQName",
@@ -15989,7 +16444,7 @@ test_xmlSplitQName(void) {
test_ret++;
printf(" %d", n_ctxt);
printf(" %d", n_name);
- printf(" %d", n_prefix);
+ printf(" %d", n_prefixOut);
printf("\n");
}
}
@@ -16009,7 +16464,7 @@ test_xmlStringCurrentChar(void) {
int ret_val;
xmlParserCtxtPtr ctxt; /* the XML parser context */
int n_ctxt;
- xmlChar * cur; /* pointer to the beginning of the char */
+ const xmlChar * cur; /* pointer to the beginning of the char */
int n_cur;
int * len; /* pointer to the length of the char read */
int n_len;
@@ -16022,11 +16477,11 @@ test_xmlStringCurrentChar(void) {
cur = gen_const_xmlChar_ptr(n_cur, 1);
len = gen_int_ptr(n_len, 2);
- ret_val = xmlStringCurrentChar(ctxt, (const xmlChar *)cur, len);
+ ret_val = xmlStringCurrentChar(ctxt, cur, len);
desret_int(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+ des_const_xmlChar_ptr(n_cur, cur, 1);
des_int_ptr(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -16055,7 +16510,7 @@ test_xmlStringDecodeEntities(void) {
xmlChar * ret_val;
xmlParserCtxtPtr ctxt; /* the parser context */
int n_ctxt;
- xmlChar * str; /* the input string */
+ const xmlChar * str; /* the input string */
int n_str;
int what; /* combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF */
int n_what;
@@ -16080,11 +16535,11 @@ test_xmlStringDecodeEntities(void) {
end2 = gen_xmlChar(n_end2, 4);
end3 = gen_xmlChar(n_end3, 5);
- ret_val = xmlStringDecodeEntities(ctxt, (const xmlChar *)str, what, end, end2, end3);
+ ret_val = xmlStringDecodeEntities(ctxt, str, what, end, end2, end3);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
des_int(n_what, what, 2);
des_xmlChar(n_end, end, 3);
des_xmlChar(n_end2, end2, 4);
@@ -16122,7 +16577,7 @@ test_xmlStringLenDecodeEntities(void) {
xmlChar * ret_val;
xmlParserCtxtPtr ctxt; /* the parser context */
int n_ctxt;
- xmlChar * str; /* the input string */
+ const xmlChar * str; /* the input string */
int n_str;
int len; /* the string length */
int n_len;
@@ -16154,11 +16609,11 @@ test_xmlStringLenDecodeEntities(void) {
(len > xmlStrlen(BAD_CAST str)))
len = 0;
- ret_val = xmlStringLenDecodeEntities(ctxt, (const xmlChar *)str, len, what, end, end2, end3);
+ ret_val = xmlStringLenDecodeEntities(ctxt, str, len, what, end, end2, end3);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
des_int(n_len, len, 2);
des_int(n_what, what, 3);
des_xmlChar(n_end, end, 4);
@@ -16231,13 +16686,52 @@ test_xmlSwitchEncoding(void) {
static int
-test_xmlSwitchInputEncoding(void) {
+test_xmlSwitchEncodingName(void) {
int test_ret = 0;
int mem_base;
int ret_val;
xmlParserCtxtPtr ctxt; /* the parser context */
int n_ctxt;
+ const char * encoding; /* the encoding name */
+ int n_encoding;
+
+ for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+ for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+ mem_base = xmlMemBlocks();
+ ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+ encoding = gen_const_char_ptr(n_encoding, 1);
+
+ ret_val = xmlSwitchEncodingName(ctxt, encoding);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+ des_const_char_ptr(n_encoding, encoding, 1);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlSwitchEncodingName",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_ctxt);
+ printf(" %d", n_encoding);
+ printf("\n");
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
+static int
+test_xmlSwitchInputEncoding(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ xmlParserCtxtPtr ctxt; /* the parser context, only for error reporting */
+ int n_ctxt;
xmlParserInputPtr input; /* the input stream */
int n_input;
xmlCharEncodingHandlerPtr handler; /* the encoding handler */
@@ -16318,7 +16812,7 @@ static int
test_parserInternals(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing parserInternals : 30 of 87 functions ...\n");
+ if (quiet == 0) printf("Testing parserInternals : 32 of 89 functions ...\n");
test_ret += test_inputPop();
test_ret += test_inputPush();
test_ret += test_namePop();
@@ -16332,6 +16826,7 @@ test_parserInternals(void) {
test_ret += test_xmlCreateFileParserCtxt();
test_ret += test_xmlCreateMemoryParserCtxt();
test_ret += test_xmlCreateURLParserCtxt();
+ test_ret += test_xmlCtxtErrMemory();
test_ret += test_xmlCurrentChar();
test_ret += test_xmlIsLetter();
test_ret += test_xmlNewEntityInputStream();
@@ -16348,6 +16843,7 @@ test_parserInternals(void) {
test_ret += test_xmlStringDecodeEntities();
test_ret += test_xmlStringLenDecodeEntities();
test_ret += test_xmlSwitchEncoding();
+ test_ret += test_xmlSwitchEncodingName();
test_ret += test_xmlSwitchInputEncoding();
test_ret += test_xmlSwitchToEncoding();
@@ -16355,6 +16851,75 @@ test_parserInternals(void) {
printf("Module parserInternals: %d errors\n", test_ret);
return(test_ret);
}
+#ifdef LIBXML_PATTERN_ENABLED
+
+#define gen_nb_xmlPatternPtr_ptr 1
+#define gen_xmlPatternPtr_ptr(no, nr) NULL
+#define des_xmlPatternPtr_ptr(no, val, nr)
+#endif
+
+
+static int
+test_xmlPatternCompileSafe(void) {
+ int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+ int mem_base;
+ int ret_val;
+ const xmlChar * pattern; /* the pattern to compile */
+ int n_pattern;
+ xmlDict * dict; /* an optional dictionary for interned strings */
+ int n_dict;
+ int flags; /* compilation flags, see xmlPatternFlags */
+ int n_flags;
+ const xmlChar ** namespaces; /* the prefix definitions, array of [URI, prefix] or NULL */
+ int n_namespaces;
+ xmlPatternPtr * patternOut; /* output pattern */
+ int n_patternOut;
+
+ for (n_pattern = 0;n_pattern < gen_nb_const_xmlChar_ptr;n_pattern++) {
+ for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
+ for (n_flags = 0;n_flags < gen_nb_int;n_flags++) {
+ for (n_namespaces = 0;n_namespaces < gen_nb_const_xmlChar_ptr_ptr;n_namespaces++) {
+ for (n_patternOut = 0;n_patternOut < gen_nb_xmlPatternPtr_ptr;n_patternOut++) {
+ mem_base = xmlMemBlocks();
+ pattern = gen_const_xmlChar_ptr(n_pattern, 0);
+ dict = gen_xmlDictPtr(n_dict, 1);
+ flags = gen_int(n_flags, 2);
+ namespaces = gen_const_xmlChar_ptr_ptr(n_namespaces, 3);
+ patternOut = gen_xmlPatternPtr_ptr(n_patternOut, 4);
+
+ ret_val = xmlPatternCompileSafe(pattern, dict, flags, namespaces, patternOut);
+ desret_int(ret_val);
+ call_tests++;
+ des_const_xmlChar_ptr(n_pattern, pattern, 0);
+ des_xmlDictPtr(n_dict, dict, 1);
+ des_int(n_flags, flags, 2);
+ des_const_xmlChar_ptr_ptr(n_namespaces, namespaces, 3);
+ des_xmlPatternPtr_ptr(n_patternOut, patternOut, 4);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlPatternCompileSafe",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_pattern);
+ printf(" %d", n_dict);
+ printf(" %d", n_flags);
+ printf(" %d", n_namespaces);
+ printf(" %d", n_patternOut);
+ printf("\n");
+ }
+ }
+ }
+ }
+ }
+ }
+ function_tests++;
+#endif
+
+ return(test_ret);
+}
+
static int
test_xmlPatternFromRoot(void) {
@@ -16603,9 +17168,9 @@ test_xmlStreamPush(void) {
int ret_val;
xmlStreamCtxtPtr stream; /* the stream context */
int n_stream;
- xmlChar * name; /* the current name */
+ const xmlChar * name; /* the current name */
int n_name;
- xmlChar * ns; /* the namespace name */
+ const xmlChar * ns; /* the namespace name */
int n_ns;
for (n_stream = 0;n_stream < gen_nb_xmlStreamCtxtPtr;n_stream++) {
@@ -16616,12 +17181,12 @@ test_xmlStreamPush(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
ns = gen_const_xmlChar_ptr(n_ns, 2);
- ret_val = xmlStreamPush(stream, (const xmlChar *)name, (const xmlChar *)ns);
+ ret_val = xmlStreamPush(stream, name, ns);
desret_int(ret_val);
call_tests++;
des_xmlStreamCtxtPtr(n_stream, stream, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_ns, ns, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStreamPush",
@@ -16651,9 +17216,9 @@ test_xmlStreamPushAttr(void) {
int ret_val;
xmlStreamCtxtPtr stream; /* the stream context */
int n_stream;
- xmlChar * name; /* the current name */
+ const xmlChar * name; /* the current name */
int n_name;
- xmlChar * ns; /* the namespace name */
+ const xmlChar * ns; /* the namespace name */
int n_ns;
for (n_stream = 0;n_stream < gen_nb_xmlStreamCtxtPtr;n_stream++) {
@@ -16664,12 +17229,12 @@ test_xmlStreamPushAttr(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
ns = gen_const_xmlChar_ptr(n_ns, 2);
- ret_val = xmlStreamPushAttr(stream, (const xmlChar *)name, (const xmlChar *)ns);
+ ret_val = xmlStreamPushAttr(stream, name, ns);
desret_int(ret_val);
call_tests++;
des_xmlStreamCtxtPtr(n_stream, stream, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_ns, ns, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStreamPushAttr",
@@ -16699,9 +17264,9 @@ test_xmlStreamPushNode(void) {
int ret_val;
xmlStreamCtxtPtr stream; /* the stream context */
int n_stream;
- xmlChar * name; /* the current name */
+ const xmlChar * name; /* the current name */
int n_name;
- xmlChar * ns; /* the namespace name */
+ const xmlChar * ns; /* the namespace name */
int n_ns;
int nodeType; /* the type of the node being pushed */
int n_nodeType;
@@ -16716,12 +17281,12 @@ test_xmlStreamPushNode(void) {
ns = gen_const_xmlChar_ptr(n_ns, 2);
nodeType = gen_int(n_nodeType, 3);
- ret_val = xmlStreamPushNode(stream, (const xmlChar *)name, (const xmlChar *)ns, nodeType);
+ ret_val = xmlStreamPushNode(stream, name, ns, nodeType);
desret_int(ret_val);
call_tests++;
des_xmlStreamCtxtPtr(n_stream, stream, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_ns, ns, 2);
des_int(n_nodeType, nodeType, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -16782,7 +17347,8 @@ static int
test_pattern(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing pattern : 10 of 15 functions ...\n");
+ if (quiet == 0) printf("Testing pattern : 11 of 16 functions ...\n");
+ test_ret += test_xmlPatternCompileSafe();
test_ret += test_xmlPatternFromRoot();
test_ret += test_xmlPatternGetStreamCtxt();
test_ret += test_xmlPatternMatch();
@@ -17092,7 +17658,7 @@ test_xmlRelaxNGNewMemParserCtxt(void) {
#if defined(LIBXML_SCHEMAS_ENABLED)
int mem_base;
xmlRelaxNGParserCtxtPtr ret_val;
- char * buffer; /* a pointer to a char array containing the schemas */
+ const char * buffer; /* a pointer to a char array containing the schemas */
int n_buffer;
int size; /* the size of the array */
int n_size;
@@ -17106,10 +17672,10 @@ test_xmlRelaxNGNewMemParserCtxt(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlRelaxNGNewMemParserCtxt((const char *)buffer, size);
+ ret_val = xmlRelaxNGNewMemParserCtxt(buffer, size);
desret_xmlRelaxNGParserCtxtPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+ des_const_char_ptr(n_buffer, buffer, 0);
des_int(n_size, size, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -17136,17 +17702,17 @@ test_xmlRelaxNGNewParserCtxt(void) {
#if defined(LIBXML_SCHEMAS_ENABLED)
int mem_base;
xmlRelaxNGParserCtxtPtr ret_val;
- char * URL; /* the location of the schema */
+ const char * URL; /* the location of the schema */
int n_URL;
for (n_URL = 0;n_URL < gen_nb_const_char_ptr;n_URL++) {
mem_base = xmlMemBlocks();
URL = gen_const_char_ptr(n_URL, 0);
- ret_val = xmlRelaxNGNewParserCtxt((const char *)URL);
+ ret_val = xmlRelaxNGNewParserCtxt(URL);
desret_xmlRelaxNGParserCtxtPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_URL, (const char *)URL, 0);
+ des_const_char_ptr(n_URL, URL, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlRelaxNGNewParserCtxt",
@@ -17369,7 +17935,7 @@ test_xmlRelaxNGValidatePushCData(void) {
int ret_val;
xmlRelaxNGValidCtxtPtr ctxt; /* the RelaxNG validation context */
int n_ctxt;
- xmlChar * data; /* some character data read */
+ const xmlChar * data; /* some character data read */
int n_data;
int len; /* the length of the data */
int n_len;
@@ -17385,11 +17951,11 @@ test_xmlRelaxNGValidatePushCData(void) {
(len > xmlStrlen(BAD_CAST data)))
len = 0;
- ret_val = xmlRelaxNGValidatePushCData(ctxt, (const xmlChar *)data, len);
+ ret_val = xmlRelaxNGValidatePushCData(ctxt, data, len);
desret_int(ret_val);
call_tests++;
des_xmlRelaxNGValidCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_data, (const xmlChar *)data, 1);
+ des_const_xmlChar_ptr(n_data, data, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -17751,30 +18317,30 @@ test_xmlAddNextSibling(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlNodePtr cur; /* the child node */
+ xmlNodePtr prev; /* the target node */
+ int n_prev;
+ xmlNodePtr cur; /* the new node */
int n_cur;
- xmlNodePtr elem; /* the new node */
- int n_elem;
- for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
- for (n_elem = 0;n_elem < gen_nb_xmlNodePtr_in;n_elem++) {
+ for (n_prev = 0;n_prev < gen_nb_xmlNodePtr;n_prev++) {
+ for (n_cur = 0;n_cur < gen_nb_xmlNodePtr_in;n_cur++) {
mem_base = xmlMemBlocks();
- cur = gen_xmlNodePtr(n_cur, 0);
- elem = gen_xmlNodePtr_in(n_elem, 1);
+ prev = gen_xmlNodePtr(n_prev, 0);
+ cur = gen_xmlNodePtr_in(n_cur, 1);
- ret_val = xmlAddNextSibling(cur, elem);
- if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }
+ ret_val = xmlAddNextSibling(prev, cur);
+ if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }
desret_xmlNodePtr(ret_val);
call_tests++;
- des_xmlNodePtr(n_cur, cur, 0);
- des_xmlNodePtr_in(n_elem, elem, 1);
+ des_xmlNodePtr(n_prev, prev, 0);
+ des_xmlNodePtr_in(n_cur, cur, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlAddNextSibling",
xmlMemBlocks() - mem_base);
test_ret++;
+ printf(" %d", n_prev);
printf(" %d", n_cur);
- printf(" %d", n_elem);
printf("\n");
}
}
@@ -17792,30 +18358,30 @@ test_xmlAddPrevSibling(void) {
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
int mem_base;
xmlNodePtr ret_val;
- xmlNodePtr cur; /* the child node */
+ xmlNodePtr next; /* the target node */
+ int n_next;
+ xmlNodePtr cur; /* the new node */
int n_cur;
- xmlNodePtr elem; /* the new node */
- int n_elem;
- for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
- for (n_elem = 0;n_elem < gen_nb_xmlNodePtr_in;n_elem++) {
+ for (n_next = 0;n_next < gen_nb_xmlNodePtr;n_next++) {
+ for (n_cur = 0;n_cur < gen_nb_xmlNodePtr_in;n_cur++) {
mem_base = xmlMemBlocks();
- cur = gen_xmlNodePtr(n_cur, 0);
- elem = gen_xmlNodePtr_in(n_elem, 1);
+ next = gen_xmlNodePtr(n_next, 0);
+ cur = gen_xmlNodePtr_in(n_cur, 1);
- ret_val = xmlAddPrevSibling(cur, elem);
- if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }
+ ret_val = xmlAddPrevSibling(next, cur);
+ if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }
desret_xmlNodePtr(ret_val);
call_tests++;
- des_xmlNodePtr(n_cur, cur, 0);
- des_xmlNodePtr_in(n_elem, elem, 1);
+ des_xmlNodePtr(n_next, next, 0);
+ des_xmlNodePtr_in(n_cur, cur, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlAddPrevSibling",
xmlMemBlocks() - mem_base);
test_ret++;
+ printf(" %d", n_next);
printf(" %d", n_cur);
- printf(" %d", n_elem);
printf("\n");
}
}
@@ -17833,30 +18399,30 @@ test_xmlAddSibling(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlNodePtr cur; /* the child node */
+ xmlNodePtr node; /* the target node */
+ int n_node;
+ xmlNodePtr cur; /* the new node */
int n_cur;
- xmlNodePtr elem; /* the new node */
- int n_elem;
- for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
- for (n_elem = 0;n_elem < gen_nb_xmlNodePtr_in;n_elem++) {
+ for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+ for (n_cur = 0;n_cur < gen_nb_xmlNodePtr_in;n_cur++) {
mem_base = xmlMemBlocks();
- cur = gen_xmlNodePtr(n_cur, 0);
- elem = gen_xmlNodePtr_in(n_elem, 1);
+ node = gen_xmlNodePtr(n_node, 0);
+ cur = gen_xmlNodePtr_in(n_cur, 1);
- ret_val = xmlAddSibling(cur, elem);
- if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }
+ ret_val = xmlAddSibling(node, cur);
+ if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }
desret_xmlNodePtr(ret_val);
call_tests++;
- des_xmlNodePtr(n_cur, cur, 0);
- des_xmlNodePtr_in(n_elem, elem, 1);
+ des_xmlNodePtr(n_node, node, 0);
+ des_xmlNodePtr_in(n_cur, cur, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlAddSibling",
xmlMemBlocks() - mem_base);
test_ret++;
+ printf(" %d", n_node);
printf(" %d", n_cur);
- printf(" %d", n_elem);
printf("\n");
}
}
@@ -17880,7 +18446,7 @@ test_xmlAttrSerializeTxtContent(void) {
int n_doc;
xmlAttrPtr attr; /* the attribute node */
int n_attr;
- xmlChar * string; /* the text content */
+ const xmlChar * string; /* the text content */
int n_string;
for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
@@ -17893,12 +18459,12 @@ test_xmlAttrSerializeTxtContent(void) {
attr = gen_xmlAttrPtr(n_attr, 2);
string = gen_const_xmlChar_ptr(n_string, 3);
- xmlAttrSerializeTxtContent(buf, doc, attr, (const xmlChar *)string);
+ xmlAttrSerializeTxtContent(buf, doc, attr, string);
call_tests++;
des_xmlBufferPtr(n_buf, buf, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlAttrPtr(n_attr, attr, 2);
- des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 3);
+ des_const_xmlChar_ptr(n_string, string, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlAttrSerializeTxtContent",
@@ -17932,17 +18498,17 @@ test_xmlBufContent(void) {
int mem_base;
xmlChar * ret_val;
- xmlBuf * buf; /* the buffer */
+ const xmlBuf * buf; /* the buffer */
int n_buf;
for (n_buf = 0;n_buf < gen_nb_const_xmlBuf_ptr;n_buf++) {
mem_base = xmlMemBlocks();
buf = gen_const_xmlBuf_ptr(n_buf, 0);
- ret_val = xmlBufContent((const xmlBuf *)buf);
+ ret_val = xmlBufContent(buf);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlBuf_ptr(n_buf, (const xmlBuf *)buf, 0);
+ des_const_xmlBuf_ptr(n_buf, buf, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBufContent",
@@ -18006,7 +18572,7 @@ test_xmlBufGetNodeContent(void) {
int ret_val;
xmlBufPtr buf; /* a buffer xmlBufPtr */
int n_buf;
- xmlNode * cur; /* the node being read */
+ const xmlNode * cur; /* the node being read */
int n_cur;
for (n_buf = 0;n_buf < gen_nb_xmlBufPtr;n_buf++) {
@@ -18015,11 +18581,11 @@ test_xmlBufGetNodeContent(void) {
buf = gen_xmlBufPtr(n_buf, 0);
cur = gen_const_xmlNode_ptr(n_cur, 1);
- ret_val = xmlBufGetNodeContent(buf, (const xmlNode *)cur);
+ ret_val = xmlBufGetNodeContent(buf, cur);
desret_int(ret_val);
call_tests++;
des_xmlBufPtr(n_buf, buf, 0);
- des_const_xmlNode_ptr(n_cur, (const xmlNode *)cur, 1);
+ des_const_xmlNode_ptr(n_cur, cur, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBufGetNodeContent",
@@ -18075,7 +18641,7 @@ test_xmlBufferAdd(void) {
int ret_val;
xmlBufferPtr buf; /* the buffer to dump */
int n_buf;
- xmlChar * str; /* the #xmlChar string */
+ const xmlChar * str; /* the #xmlChar string */
int n_str;
int len; /* the number of #xmlChar to add */
int n_len;
@@ -18091,11 +18657,11 @@ test_xmlBufferAdd(void) {
(len > xmlStrlen(BAD_CAST str)))
len = 0;
- ret_val = xmlBufferAdd(buf, (const xmlChar *)str, len);
+ ret_val = xmlBufferAdd(buf, str, len);
desret_int(ret_val);
call_tests++;
des_xmlBufferPtr(n_buf, buf, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -18124,7 +18690,7 @@ test_xmlBufferAddHead(void) {
int ret_val;
xmlBufferPtr buf; /* the buffer */
int n_buf;
- xmlChar * str; /* the #xmlChar string */
+ const xmlChar * str; /* the #xmlChar string */
int n_str;
int len; /* the number of #xmlChar to add */
int n_len;
@@ -18140,11 +18706,11 @@ test_xmlBufferAddHead(void) {
(len > xmlStrlen(BAD_CAST str)))
len = 0;
- ret_val = xmlBufferAddHead(buf, (const xmlChar *)str, len);
+ ret_val = xmlBufferAddHead(buf, str, len);
desret_int(ret_val);
call_tests++;
des_xmlBufferPtr(n_buf, buf, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -18173,7 +18739,7 @@ test_xmlBufferCCat(void) {
int ret_val;
xmlBufferPtr buf; /* the buffer to dump */
int n_buf;
- char * str; /* the C char string */
+ const char * str; /* the C char string */
int n_str;
for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
@@ -18182,11 +18748,11 @@ test_xmlBufferCCat(void) {
buf = gen_xmlBufferPtr(n_buf, 0);
str = gen_const_char_ptr(n_str, 1);
- ret_val = xmlBufferCCat(buf, (const char *)str);
+ ret_val = xmlBufferCCat(buf, str);
desret_int(ret_val);
call_tests++;
des_xmlBufferPtr(n_buf, buf, 0);
- des_const_char_ptr(n_str, (const char *)str, 1);
+ des_const_char_ptr(n_str, str, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBufferCCat",
@@ -18212,7 +18778,7 @@ test_xmlBufferCat(void) {
int ret_val;
xmlBufferPtr buf; /* the buffer to add to */
int n_buf;
- xmlChar * str; /* the #xmlChar string */
+ const xmlChar * str; /* the #xmlChar string */
int n_str;
for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
@@ -18221,11 +18787,11 @@ test_xmlBufferCat(void) {
buf = gen_xmlBufferPtr(n_buf, 0);
str = gen_const_xmlChar_ptr(n_str, 1);
- ret_val = xmlBufferCat(buf, (const xmlChar *)str);
+ ret_val = xmlBufferCat(buf, str);
desret_int(ret_val);
call_tests++;
des_xmlBufferPtr(n_buf, buf, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBufferCat",
@@ -18253,17 +18819,17 @@ test_xmlBufferContent(void) {
int mem_base;
const xmlChar * ret_val;
- xmlBuffer * buf; /* the buffer */
+ const xmlBuffer * buf; /* the buffer */
int n_buf;
for (n_buf = 0;n_buf < gen_nb_const_xmlBuffer_ptr;n_buf++) {
mem_base = xmlMemBlocks();
buf = gen_const_xmlBuffer_ptr(n_buf, 0);
- ret_val = xmlBufferContent((const xmlBuffer *)buf);
+ ret_val = xmlBufferContent(buf);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlBuffer_ptr(n_buf, (const xmlBuffer *)buf, 0);
+ des_const_xmlBuffer_ptr(n_buf, buf, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBufferContent",
@@ -18431,17 +18997,17 @@ test_xmlBufferLength(void) {
int mem_base;
int ret_val;
- xmlBuffer * buf; /* the buffer */
+ const xmlBuffer * buf; /* the buffer */
int n_buf;
for (n_buf = 0;n_buf < gen_nb_const_xmlBuffer_ptr;n_buf++) {
mem_base = xmlMemBlocks();
buf = gen_const_xmlBuffer_ptr(n_buf, 0);
- ret_val = xmlBufferLength((const xmlBuffer *)buf);
+ ret_val = xmlBufferLength(buf);
desret_int(ret_val);
call_tests++;
- des_const_xmlBuffer_ptr(n_buf, (const xmlBuffer *)buf, 0);
+ des_const_xmlBuffer_ptr(n_buf, buf, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBufferLength",
@@ -18579,7 +19145,7 @@ test_xmlBufferWriteCHAR(void) {
int mem_base;
xmlBufferPtr buf; /* the XML buffer */
int n_buf;
- xmlChar * string; /* the string to add */
+ const xmlChar * string; /* the string to add */
int n_string;
for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
@@ -18588,10 +19154,10 @@ test_xmlBufferWriteCHAR(void) {
buf = gen_xmlBufferPtr(n_buf, 0);
string = gen_const_xmlChar_ptr(n_string, 1);
- xmlBufferWriteCHAR(buf, (const xmlChar *)string);
+ xmlBufferWriteCHAR(buf, string);
call_tests++;
des_xmlBufferPtr(n_buf, buf, 0);
- des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 1);
+ des_const_xmlChar_ptr(n_string, string, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBufferWriteCHAR",
@@ -18616,7 +19182,7 @@ test_xmlBufferWriteChar(void) {
int mem_base;
xmlBufferPtr buf; /* the XML buffer output */
int n_buf;
- char * string; /* the string to add */
+ const char * string; /* the string to add */
int n_string;
for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
@@ -18625,10 +19191,10 @@ test_xmlBufferWriteChar(void) {
buf = gen_xmlBufferPtr(n_buf, 0);
string = gen_const_char_ptr(n_string, 1);
- xmlBufferWriteChar(buf, (const char *)string);
+ xmlBufferWriteChar(buf, string);
call_tests++;
des_xmlBufferPtr(n_buf, buf, 0);
- des_const_char_ptr(n_string, (const char *)string, 1);
+ des_const_char_ptr(n_string, string, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBufferWriteChar",
@@ -18653,7 +19219,7 @@ test_xmlBufferWriteQuotedString(void) {
int mem_base;
xmlBufferPtr buf; /* the XML buffer output */
int n_buf;
- xmlChar * string; /* the string to add */
+ const xmlChar * string; /* the string to add */
int n_string;
for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
@@ -18662,10 +19228,10 @@ test_xmlBufferWriteQuotedString(void) {
buf = gen_xmlBufferPtr(n_buf, 0);
string = gen_const_xmlChar_ptr(n_string, 1);
- xmlBufferWriteQuotedString(buf, (const xmlChar *)string);
+ xmlBufferWriteQuotedString(buf, string);
call_tests++;
des_xmlBufferPtr(n_buf, buf, 0);
- des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 1);
+ des_const_xmlChar_ptr(n_string, string, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBufferWriteQuotedString",
@@ -18689,9 +19255,9 @@ test_xmlBuildQName(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * ncname; /* the Name */
+ const xmlChar * ncname; /* the Name */
int n_ncname;
- xmlChar * prefix; /* the prefix */
+ const xmlChar * prefix; /* the prefix */
int n_prefix;
xmlChar * memory; /* preallocated memory */
int n_memory;
@@ -18711,15 +19277,15 @@ test_xmlBuildQName(void) {
(len > xmlStrlen(BAD_CAST prefix)))
len = 0;
- ret_val = xmlBuildQName((const xmlChar *)ncname, (const xmlChar *)prefix, memory, len);
+ ret_val = xmlBuildQName(ncname, prefix, memory, len);
if ((ret_val != NULL) && (ret_val != ncname) &&
(ret_val != prefix) && (ret_val != memory))
xmlFree(ret_val);
ret_val = NULL;
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_ncname, (const xmlChar *)ncname, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+ des_const_xmlChar_ptr(n_ncname, ncname, 0);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
des_xmlChar_ptr(n_memory, memory, 2);
des_int(n_len, len, 3);
xmlResetLastError();
@@ -18825,7 +19391,7 @@ test_xmlCopyDtd(void) {
#if defined(LIBXML_TREE_ENABLED)
int mem_base;
xmlDtdPtr ret_val;
- xmlDtdPtr dtd; /* the dtd */
+ xmlDtdPtr dtd; /* the DTD */
int n_dtd;
for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
@@ -19073,13 +19639,13 @@ test_xmlCreateIntSubset(void) {
int mem_base;
xmlDtdPtr ret_val;
- xmlDocPtr doc; /* the document pointer */
+ xmlDocPtr doc; /* the document pointer (optional) */
int n_doc;
- xmlChar * name; /* the DTD name */
+ const xmlChar * name; /* the DTD name (optional) */
int n_name;
- xmlChar * ExternalID; /* the external (PUBLIC) ID */
+ const xmlChar * ExternalID; /* the external (PUBLIC) ID (optional) */
int n_ExternalID;
- xmlChar * SystemID; /* the system ID */
+ const xmlChar * SystemID; /* the system ID (optional) */
int n_SystemID;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -19092,13 +19658,13 @@ test_xmlCreateIntSubset(void) {
ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 2);
SystemID = gen_const_xmlChar_ptr(n_SystemID, 3);
- ret_val = xmlCreateIntSubset(doc, (const xmlChar *)name, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+ ret_val = xmlCreateIntSubset(doc, name, ExternalID, SystemID);
desret_xmlDtdPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 2);
- des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 3);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 2);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCreateIntSubset",
@@ -19583,7 +20149,7 @@ test_xmlDocDumpFormatMemoryEnc(void) {
int n_doc_txt_ptr;
int * doc_txt_len; /* Length of the generated XML text */
int n_doc_txt_len;
- char * txt_encoding; /* Character encoding to use when generating XML text */
+ const char * txt_encoding; /* Character encoding to use when generating XML text */
int n_txt_encoding;
int format; /* should formatting spaces been added */
int n_format;
@@ -19600,12 +20166,12 @@ test_xmlDocDumpFormatMemoryEnc(void) {
txt_encoding = gen_const_char_ptr(n_txt_encoding, 3);
format = gen_int(n_format, 4);
- xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len, (const char *)txt_encoding, format);
+ xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len, txt_encoding, format);
call_tests++;
des_xmlDocPtr(n_out_doc, out_doc, 0);
des_xmlChar_ptr_ptr(n_doc_txt_ptr, doc_txt_ptr, 1);
des_int_ptr(n_doc_txt_len, doc_txt_len, 2);
- des_const_char_ptr(n_txt_encoding, (const char *)txt_encoding, 3);
+ des_const_char_ptr(n_txt_encoding, txt_encoding, 3);
des_int(n_format, format, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -19689,7 +20255,7 @@ test_xmlDocDumpMemoryEnc(void) {
int n_doc_txt_ptr;
int * doc_txt_len; /* Length of the generated XML text */
int n_doc_txt_len;
- char * txt_encoding; /* Character encoding to use when generating XML text */
+ const char * txt_encoding; /* Character encoding to use when generating XML text */
int n_txt_encoding;
for (n_out_doc = 0;n_out_doc < gen_nb_xmlDocPtr;n_out_doc++) {
@@ -19702,12 +20268,12 @@ test_xmlDocDumpMemoryEnc(void) {
doc_txt_len = gen_int_ptr(n_doc_txt_len, 2);
txt_encoding = gen_const_char_ptr(n_txt_encoding, 3);
- xmlDocDumpMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len, (const char *)txt_encoding);
+ xmlDocDumpMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len, txt_encoding);
call_tests++;
des_xmlDocPtr(n_out_doc, out_doc, 0);
des_xmlChar_ptr_ptr(n_doc_txt_ptr, doc_txt_ptr, 1);
des_int_ptr(n_doc_txt_len, doc_txt_len, 2);
- des_const_char_ptr(n_txt_encoding, (const char *)txt_encoding, 3);
+ des_const_char_ptr(n_txt_encoding, txt_encoding, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlDocDumpMemoryEnc",
@@ -19784,17 +20350,17 @@ test_xmlDocGetRootElement(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDoc * doc; /* the document */
+ const xmlDoc * doc; /* the document */
int n_doc;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
mem_base = xmlMemBlocks();
doc = gen_const_xmlDoc_ptr(n_doc, 0);
- ret_val = xmlDocGetRootElement((const xmlDoc *)doc);
+ ret_val = xmlDocGetRootElement(doc);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlDocGetRootElement",
@@ -19988,17 +20554,17 @@ test_xmlGetDocCompressMode(void) {
int mem_base;
int ret_val;
- xmlDoc * doc; /* the document */
+ const xmlDoc * doc; /* the document */
int n_doc;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
mem_base = xmlMemBlocks();
doc = gen_const_xmlDoc_ptr(n_doc, 0);
- ret_val = xmlGetDocCompressMode((const xmlDoc *)doc);
+ ret_val = xmlGetDocCompressMode(doc);
desret_int(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetDocCompressMode",
@@ -20020,17 +20586,17 @@ test_xmlGetIntSubset(void) {
int mem_base;
xmlDtdPtr ret_val;
- xmlDoc * doc; /* the document pointer */
+ const xmlDoc * doc; /* the document pointer */
int n_doc;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
mem_base = xmlMemBlocks();
doc = gen_const_xmlDoc_ptr(n_doc, 0);
- ret_val = xmlGetIntSubset((const xmlDoc *)doc);
+ ret_val = xmlGetIntSubset(doc);
desret_xmlDtdPtr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetIntSubset",
@@ -20052,17 +20618,17 @@ test_xmlGetLastChild(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlNode * parent; /* the parent node */
+ const xmlNode * parent; /* the parent node */
int n_parent;
for (n_parent = 0;n_parent < gen_nb_const_xmlNode_ptr;n_parent++) {
mem_base = xmlMemBlocks();
parent = gen_const_xmlNode_ptr(n_parent, 0);
- ret_val = xmlGetLastChild((const xmlNode *)parent);
+ ret_val = xmlGetLastChild(parent);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_parent, (const xmlNode *)parent, 0);
+ des_const_xmlNode_ptr(n_parent, parent, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetLastChild",
@@ -20084,17 +20650,17 @@ test_xmlGetLineNo(void) {
int mem_base;
long ret_val;
- xmlNode * node; /* valid node */
+ const xmlNode * node; /* valid node */
int n_node;
for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
mem_base = xmlMemBlocks();
node = gen_const_xmlNode_ptr(n_node, 0);
- ret_val = xmlGetLineNo((const xmlNode *)node);
+ ret_val = xmlGetLineNo(node);
desret_long(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_node, (const xmlNode *)node, 0);
+ des_const_xmlNode_ptr(n_node, node, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetLineNo",
@@ -20116,9 +20682,9 @@ test_xmlGetNoNsProp(void) {
int mem_base;
xmlChar * ret_val;
- xmlNode * node; /* the node */
+ const xmlNode * node; /* the node */
int n_node;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
@@ -20127,11 +20693,11 @@ test_xmlGetNoNsProp(void) {
node = gen_const_xmlNode_ptr(n_node, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlGetNoNsProp((const xmlNode *)node, (const xmlChar *)name);
+ ret_val = xmlGetNoNsProp(node, name);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_node, (const xmlNode *)node, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlNode_ptr(n_node, node, 0);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetNoNsProp",
@@ -20156,17 +20722,17 @@ test_xmlGetNodePath(void) {
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
int mem_base;
xmlChar * ret_val;
- xmlNode * node; /* a node */
+ const xmlNode * node; /* a node */
int n_node;
for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
mem_base = xmlMemBlocks();
node = gen_const_xmlNode_ptr(n_node, 0);
- ret_val = xmlGetNodePath((const xmlNode *)node);
+ ret_val = xmlGetNodePath(node);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_node, (const xmlNode *)node, 0);
+ des_const_xmlNode_ptr(n_node, node, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetNodePath",
@@ -20193,17 +20759,27 @@ test_xmlGetNsList(void) {
}
+static int
+test_xmlGetNsListSafe(void) {
+ int test_ret = 0;
+
+
+ /* missing type support */
+ return(test_ret);
+}
+
+
static int
test_xmlGetNsProp(void) {
int test_ret = 0;
int mem_base;
xmlChar * ret_val;
- xmlNode * node; /* the node */
+ const xmlNode * node; /* the node */
int n_node;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
- xmlChar * nameSpace; /* the URI of the namespace */
+ const xmlChar * nameSpace; /* the URI of the namespace */
int n_nameSpace;
for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
@@ -20214,12 +20790,12 @@ test_xmlGetNsProp(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
nameSpace = gen_const_xmlChar_ptr(n_nameSpace, 2);
- ret_val = xmlGetNsProp((const xmlNode *)node, (const xmlChar *)name, (const xmlChar *)nameSpace);
+ ret_val = xmlGetNsProp(node, name, nameSpace);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_node, (const xmlNode *)node, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_nameSpace, (const xmlChar *)nameSpace, 2);
+ des_const_xmlNode_ptr(n_node, node, 0);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_nameSpace, nameSpace, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetNsProp",
@@ -20245,9 +20821,9 @@ test_xmlGetProp(void) {
int mem_base;
xmlChar * ret_val;
- xmlNode * node; /* the node */
+ const xmlNode * node; /* the node */
int n_node;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
@@ -20256,11 +20832,11 @@ test_xmlGetProp(void) {
node = gen_const_xmlNode_ptr(n_node, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlGetProp((const xmlNode *)node, (const xmlChar *)name);
+ ret_val = xmlGetProp(node, name);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_node, (const xmlNode *)node, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlNode_ptr(n_node, node, 0);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetProp",
@@ -20284,11 +20860,11 @@ test_xmlHasNsProp(void) {
int mem_base;
xmlAttrPtr ret_val;
- xmlNode * node; /* the node */
+ const xmlNode * node; /* the node */
int n_node;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
- xmlChar * nameSpace; /* the URI of the namespace */
+ const xmlChar * nameSpace; /* the URI of the namespace */
int n_nameSpace;
for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
@@ -20299,12 +20875,12 @@ test_xmlHasNsProp(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
nameSpace = gen_const_xmlChar_ptr(n_nameSpace, 2);
- ret_val = xmlHasNsProp((const xmlNode *)node, (const xmlChar *)name, (const xmlChar *)nameSpace);
+ ret_val = xmlHasNsProp(node, name, nameSpace);
desret_xmlAttrPtr(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_node, (const xmlNode *)node, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_nameSpace, (const xmlChar *)nameSpace, 2);
+ des_const_xmlNode_ptr(n_node, node, 0);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_nameSpace, nameSpace, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlHasNsProp",
@@ -20330,9 +20906,9 @@ test_xmlHasProp(void) {
int mem_base;
xmlAttrPtr ret_val;
- xmlNode * node; /* the node */
+ const xmlNode * node; /* the node */
int n_node;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
@@ -20341,11 +20917,11 @@ test_xmlHasProp(void) {
node = gen_const_xmlNode_ptr(n_node, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlHasProp((const xmlNode *)node, (const xmlChar *)name);
+ ret_val = xmlHasProp(node, name);
desret_xmlAttrPtr(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_node, (const xmlNode *)node, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlNode_ptr(n_node, node, 0);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlHasProp",
@@ -20369,17 +20945,17 @@ test_xmlIsBlankNode(void) {
int mem_base;
int ret_val;
- xmlNode * node; /* the node */
+ const xmlNode * node; /* the node */
int n_node;
for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
mem_base = xmlMemBlocks();
node = gen_const_xmlNode_ptr(n_node, 0);
- ret_val = xmlIsBlankNode((const xmlNode *)node);
+ ret_val = xmlIsBlankNode(node);
desret_int(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_node, (const xmlNode *)node, 0);
+ des_const_xmlNode_ptr(n_node, node, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlIsBlankNode",
@@ -20401,9 +20977,9 @@ test_xmlIsXHTML(void) {
int mem_base;
int ret_val;
- xmlChar * systemID; /* the system identifier */
+ const xmlChar * systemID; /* the system identifier */
int n_systemID;
- xmlChar * publicID; /* the public identifier */
+ const xmlChar * publicID; /* the public identifier */
int n_publicID;
for (n_systemID = 0;n_systemID < gen_nb_const_xmlChar_ptr;n_systemID++) {
@@ -20412,11 +20988,11 @@ test_xmlIsXHTML(void) {
systemID = gen_const_xmlChar_ptr(n_systemID, 0);
publicID = gen_const_xmlChar_ptr(n_publicID, 1);
- ret_val = xmlIsXHTML((const xmlChar *)systemID, (const xmlChar *)publicID);
+ ret_val = xmlIsXHTML(systemID, publicID);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_systemID, (const xmlChar *)systemID, 0);
- des_const_xmlChar_ptr(n_publicID, (const xmlChar *)publicID, 1);
+ des_const_xmlChar_ptr(n_systemID, systemID, 0);
+ des_const_xmlChar_ptr(n_publicID, publicID, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlIsXHTML",
@@ -20474,11 +21050,11 @@ test_xmlNewCDataBlock(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDocPtr doc; /* the document */
+ xmlDocPtr doc; /* the target document (optional) */
int n_doc;
- xmlChar * content; /* the CDATA block content content */
+ const xmlChar * content; /* raw text content (optional) */
int n_content;
- int len; /* the length of the block */
+ int len; /* size of text content */
int n_len;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -20492,11 +21068,11 @@ test_xmlNewCDataBlock(void) {
(len > xmlStrlen(BAD_CAST content)))
len = 0;
- ret_val = xmlNewCDataBlock(doc, (const xmlChar *)content, len);
+ ret_val = xmlNewCDataBlock(doc, content, len);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -20523,9 +21099,9 @@ test_xmlNewCharRef(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDocPtr doc; /* the document */
+ xmlDocPtr doc; /* the target document (optional) */
int n_doc;
- xmlChar * name; /* the char ref string, starting with # or " ... ;" */
+ const xmlChar * name; /* the entity name */
int n_name;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -20534,11 +21110,11 @@ test_xmlNewCharRef(void) {
doc = gen_xmlDocPtr(n_doc, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlNewCharRef(doc, (const xmlChar *)name);
+ ret_val = xmlNewCharRef(doc, name);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewCharRef",
@@ -20566,11 +21142,11 @@ test_xmlNewChild(void) {
xmlNodePtr ret_val;
xmlNodePtr parent; /* the parent node */
int n_parent;
- xmlNsPtr ns; /* a namespace if any */
+ xmlNsPtr ns; /* a namespace (optional) */
int n_ns;
- xmlChar * name; /* the name of the child */
+ const xmlChar * name; /* the name of the child */
int n_name;
- xmlChar * content; /* the XML content of the child if any. */
+ const xmlChar * content; /* text content with XML references (optional) */
int n_content;
for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
@@ -20583,13 +21159,13 @@ test_xmlNewChild(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
content = gen_const_xmlChar_ptr(n_content, 3);
- ret_val = xmlNewChild(parent, ns, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlNewChild(parent, ns, name, content);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlNodePtr(n_parent, parent, 0);
des_xmlNsPtr(n_ns, ns, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_content, content, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewChild",
@@ -20619,17 +21195,17 @@ test_xmlNewComment(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlChar * content; /* the comment content */
+ const xmlChar * content; /* the comment content (optional) */
int n_content;
for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
mem_base = xmlMemBlocks();
content = gen_const_xmlChar_ptr(n_content, 0);
- ret_val = xmlNewComment((const xmlChar *)content);
+ ret_val = xmlNewComment(content);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 0);
+ des_const_xmlChar_ptr(n_content, content, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewComment",
@@ -20651,17 +21227,17 @@ test_xmlNewDoc(void) {
int mem_base;
xmlDocPtr ret_val;
- xmlChar * version; /* xmlChar string giving the version of XML "1.0" */
+ const xmlChar * version; /* XML version string like "1.0" (optional) */
int n_version;
for (n_version = 0;n_version < gen_nb_const_xmlChar_ptr;n_version++) {
mem_base = xmlMemBlocks();
version = gen_const_xmlChar_ptr(n_version, 0);
- ret_val = xmlNewDoc((const xmlChar *)version);
+ ret_val = xmlNewDoc(version);
desret_xmlDocPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_version, (const xmlChar *)version, 0);
+ des_const_xmlChar_ptr(n_version, version, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewDoc",
@@ -20685,7 +21261,7 @@ test_xmlNewDocComment(void) {
xmlNodePtr ret_val;
xmlDocPtr doc; /* the document */
int n_doc;
- xmlChar * content; /* the comment content */
+ const xmlChar * content; /* the comment content */
int n_content;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -20694,11 +21270,11 @@ test_xmlNewDocComment(void) {
doc = gen_xmlDocPtr(n_doc, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- ret_val = xmlNewDocComment(doc, (const xmlChar *)content);
+ ret_val = xmlNewDocComment(doc, content);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewDocComment",
@@ -20723,7 +21299,7 @@ test_xmlNewDocFragment(void) {
#if defined(LIBXML_TREE_ENABLED)
int mem_base;
xmlNodePtr ret_val;
- xmlDocPtr doc; /* the document owning the fragment */
+ xmlDocPtr doc; /* the target document (optional) */
int n_doc;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -20756,13 +21332,13 @@ test_xmlNewDocNode(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDocPtr doc; /* the document */
+ xmlDocPtr doc; /* the target document */
int n_doc;
- xmlNsPtr ns; /* namespace if any */
+ xmlNsPtr ns; /* namespace (optional) */
int n_ns;
- xmlChar * name; /* the node name */
+ const xmlChar * name; /* the node name */
int n_name;
- xmlChar * content; /* the XML text content if any */
+ const xmlChar * content; /* text content with XML references (optional) */
int n_content;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -20775,13 +21351,13 @@ test_xmlNewDocNode(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
content = gen_const_xmlChar_ptr(n_content, 3);
- ret_val = xmlNewDocNode(doc, ns, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlNewDocNode(doc, ns, name, content);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
des_xmlNsPtr(n_ns, ns, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_content, content, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewDocNode",
@@ -20809,13 +21385,13 @@ test_xmlNewDocNodeEatName(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDocPtr doc; /* the document */
+ xmlDocPtr doc; /* the target document */
int n_doc;
- xmlNsPtr ns; /* namespace if any */
+ xmlNsPtr ns; /* namespace (optional) */
int n_ns;
xmlChar * name; /* the node name */
int n_name;
- xmlChar * content; /* the XML text content if any */
+ const xmlChar * content; /* text content with XML references (optional) */
int n_content;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -20828,13 +21404,13 @@ test_xmlNewDocNodeEatName(void) {
name = gen_eaten_name(n_name, 2);
content = gen_const_xmlChar_ptr(n_content, 3);
- ret_val = xmlNewDocNodeEatName(doc, ns, name, (const xmlChar *)content);
+ ret_val = xmlNewDocNodeEatName(doc, ns, name, content);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
des_xmlNsPtr(n_ns, ns, 1);
des_eaten_name(n_name, name, 2);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+ des_const_xmlChar_ptr(n_content, content, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewDocNodeEatName",
@@ -20862,11 +21438,11 @@ test_xmlNewDocPI(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDocPtr doc; /* the target document */
+ xmlDocPtr doc; /* the target document (optional) */
int n_doc;
- xmlChar * name; /* the processing instruction name */
+ const xmlChar * name; /* the processing instruction target */
int n_name;
- xmlChar * content; /* the PI content */
+ const xmlChar * content; /* the PI content (optional) */
int n_content;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -20877,12 +21453,12 @@ test_xmlNewDocPI(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
content = gen_const_xmlChar_ptr(n_content, 2);
- ret_val = xmlNewDocPI(doc, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlNewDocPI(doc, name, content);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_content, content, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewDocPI",
@@ -20908,11 +21484,11 @@ test_xmlNewDocProp(void) {
int mem_base;
xmlAttrPtr ret_val;
- xmlDocPtr doc; /* the document */
+ xmlDocPtr doc; /* the target document (optional) */
int n_doc;
- xmlChar * name; /* the name of the attribute */
+ const xmlChar * name; /* the name of the attribute */
int n_name;
- xmlChar * value; /* the value of the attribute */
+ const xmlChar * value; /* attribute value with XML references (optional) */
int n_value;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -20923,12 +21499,12 @@ test_xmlNewDocProp(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
value = gen_const_xmlChar_ptr(n_value, 2);
- ret_val = xmlNewDocProp(doc, (const xmlChar *)name, (const xmlChar *)value);
+ ret_val = xmlNewDocProp(doc, name, value);
desret_xmlAttrPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_value, value, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewDocProp",
@@ -20956,13 +21532,13 @@ test_xmlNewDocRawNode(void) {
#ifdef LIBXML_TREE_ENABLED
int mem_base;
xmlNodePtr ret_val;
- xmlDocPtr doc; /* the document */
+ xmlDocPtr doc; /* the target document */
int n_doc;
- xmlNsPtr ns; /* namespace if any */
+ xmlNsPtr ns; /* namespace (optional) */
int n_ns;
- xmlChar * name; /* the node name */
+ const xmlChar * name; /* the node name */
int n_name;
- xmlChar * content; /* the text content if any */
+ const xmlChar * content; /* raw text content (optional) */
int n_content;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -20975,13 +21551,13 @@ test_xmlNewDocRawNode(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
content = gen_const_xmlChar_ptr(n_content, 3);
- ret_val = xmlNewDocRawNode(doc, ns, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlNewDocRawNode(doc, ns, name, content);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
des_xmlNsPtr(n_ns, ns, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_content, content, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewDocRawNode",
@@ -21011,9 +21587,9 @@ test_xmlNewDocText(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDoc * doc; /* the document */
+ const xmlDoc * doc; /* the target document */
int n_doc;
- xmlChar * content; /* the text content */
+ const xmlChar * content; /* raw text content (optional) */
int n_content;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
@@ -21022,11 +21598,11 @@ test_xmlNewDocText(void) {
doc = gen_const_xmlDoc_ptr(n_doc, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- ret_val = xmlNewDocText((const xmlDoc *)doc, (const xmlChar *)content);
+ ret_val = xmlNewDocText(doc, content);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewDocText",
@@ -21050,11 +21626,11 @@ test_xmlNewDocTextLen(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDocPtr doc; /* the document */
+ xmlDocPtr doc; /* the target document */
int n_doc;
- xmlChar * content; /* the text content */
+ const xmlChar * content; /* raw text content (optional) */
int n_content;
- int len; /* the text len. */
+ int len; /* size of text content */
int n_len;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -21068,11 +21644,11 @@ test_xmlNewDocTextLen(void) {
(len > xmlStrlen(BAD_CAST content)))
len = 0;
- ret_val = xmlNewDocTextLen(doc, (const xmlChar *)content, len);
+ ret_val = xmlNewDocTextLen(doc, content, len);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -21099,13 +21675,13 @@ test_xmlNewDtd(void) {
int mem_base;
xmlDtdPtr ret_val;
- xmlDocPtr doc; /* the document pointer */
+ xmlDocPtr doc; /* the document pointer (optional) */
int n_doc;
- xmlChar * name; /* the DTD name */
+ const xmlChar * name; /* the DTD name (optional) */
int n_name;
- xmlChar * ExternalID; /* the external ID */
+ const xmlChar * ExternalID; /* the external ID (optional) */
int n_ExternalID;
- xmlChar * SystemID; /* the system ID */
+ const xmlChar * SystemID; /* the system ID (optional) */
int n_SystemID;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -21118,13 +21694,13 @@ test_xmlNewDtd(void) {
ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 2);
SystemID = gen_const_xmlChar_ptr(n_SystemID, 3);
- ret_val = xmlNewDtd(doc, (const xmlChar *)name, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+ ret_val = xmlNewDtd(doc, name, ExternalID, SystemID);
desret_xmlDtdPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 2);
- des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 3);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_ExternalID, ExternalID, 2);
+ des_const_xmlChar_ptr(n_SystemID, SystemID, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewDtd",
@@ -21152,9 +21728,9 @@ test_xmlNewNode(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlNsPtr ns; /* namespace if any */
+ xmlNsPtr ns; /* namespace (optional) */
int n_ns;
- xmlChar * name; /* the node name */
+ const xmlChar * name; /* the node name */
int n_name;
for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
@@ -21163,11 +21739,11 @@ test_xmlNewNode(void) {
ns = gen_xmlNsPtr(n_ns, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlNewNode(ns, (const xmlChar *)name);
+ ret_val = xmlNewNode(ns, name);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlNsPtr(n_ns, ns, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewNode",
@@ -21191,7 +21767,7 @@ test_xmlNewNodeEatName(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlNsPtr ns; /* namespace if any */
+ xmlNsPtr ns; /* namespace (optional) */
int n_ns;
xmlChar * name; /* the node name */
int n_name;
@@ -21230,11 +21806,11 @@ test_xmlNewNs(void) {
int mem_base;
xmlNsPtr ret_val;
- xmlNodePtr node; /* the element carrying the namespace */
+ xmlNodePtr node; /* the element carrying the namespace (optional) */
int n_node;
- xmlChar * href; /* the URI associated */
+ const xmlChar * href; /* the URI associated */
int n_href;
- xmlChar * prefix; /* the prefix for the namespace */
+ const xmlChar * prefix; /* the prefix for the namespace (optional) */
int n_prefix;
for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
@@ -21245,13 +21821,13 @@ test_xmlNewNs(void) {
href = gen_const_xmlChar_ptr(n_href, 1);
prefix = gen_const_xmlChar_ptr(n_prefix, 2);
- ret_val = xmlNewNs(node, (const xmlChar *)href, (const xmlChar *)prefix);
+ ret_val = xmlNewNs(node, href, prefix);
if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);
desret_xmlNsPtr(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
- des_const_xmlChar_ptr(n_href, (const xmlChar *)href, 1);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 2);
+ des_const_xmlChar_ptr(n_href, href, 1);
+ des_const_xmlChar_ptr(n_prefix, prefix, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewNs",
@@ -21277,13 +21853,13 @@ test_xmlNewNsProp(void) {
int mem_base;
xmlAttrPtr ret_val;
- xmlNodePtr node; /* the holding node */
+ xmlNodePtr node; /* the parent node (optional) */
int n_node;
- xmlNsPtr ns; /* the namespace */
+ xmlNsPtr ns; /* the namespace (optional) */
int n_ns;
- xmlChar * name; /* the name of the attribute */
+ const xmlChar * name; /* the local name of the attribute */
int n_name;
- xmlChar * value; /* the value of the attribute */
+ const xmlChar * value; /* the value of the attribute (optional) */
int n_value;
for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
@@ -21296,13 +21872,13 @@ test_xmlNewNsProp(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
value = gen_const_xmlChar_ptr(n_value, 3);
- ret_val = xmlNewNsProp(node, ns, (const xmlChar *)name, (const xmlChar *)value);
+ ret_val = xmlNewNsProp(node, ns, name, value);
desret_xmlAttrPtr(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
des_xmlNsPtr(n_ns, ns, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_value, value, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewNsProp",
@@ -21330,13 +21906,13 @@ test_xmlNewNsPropEatName(void) {
int mem_base;
xmlAttrPtr ret_val;
- xmlNodePtr node; /* the holding node */
+ xmlNodePtr node; /* the parent node (optional) */
int n_node;
- xmlNsPtr ns; /* the namespace */
+ xmlNsPtr ns; /* the namespace (optional) */
int n_ns;
- xmlChar * name; /* the name of the attribute */
+ xmlChar * name; /* the local name of the attribute */
int n_name;
- xmlChar * value; /* the value of the attribute */
+ const xmlChar * value; /* the value of the attribute (optional) */
int n_value;
for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
@@ -21349,13 +21925,13 @@ test_xmlNewNsPropEatName(void) {
name = gen_eaten_name(n_name, 2);
value = gen_const_xmlChar_ptr(n_value, 3);
- ret_val = xmlNewNsPropEatName(node, ns, name, (const xmlChar *)value);
+ ret_val = xmlNewNsPropEatName(node, ns, name, value);
desret_xmlAttrPtr(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
des_xmlNsPtr(n_ns, ns, 1);
des_eaten_name(n_name, name, 2);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+ des_const_xmlChar_ptr(n_value, value, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewNsPropEatName",
@@ -21383,9 +21959,9 @@ test_xmlNewPI(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlChar * name; /* the processing instruction name */
+ const xmlChar * name; /* the processing instruction target */
int n_name;
- xmlChar * content; /* the PI content */
+ const xmlChar * content; /* the PI content (optional) */
int n_content;
for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
@@ -21394,11 +21970,11 @@ test_xmlNewPI(void) {
name = gen_const_xmlChar_ptr(n_name, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- ret_val = xmlNewPI((const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlNewPI(name, content);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_name, name, 0);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewPI",
@@ -21424,11 +22000,11 @@ test_xmlNewProp(void) {
#ifdef LIBXML_TREE_ENABLED
int mem_base;
xmlAttrPtr ret_val;
- xmlNodePtr node; /* the holding node */
+ xmlNodePtr node; /* the parent node (optional) */
int n_node;
- xmlChar * name; /* the name of the attribute */
+ const xmlChar * name; /* the name of the attribute */
int n_name;
- xmlChar * value; /* the value of the attribute */
+ const xmlChar * value; /* the value of the attribute (optional) */
int n_value;
for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
@@ -21439,12 +22015,12 @@ test_xmlNewProp(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
value = gen_const_xmlChar_ptr(n_value, 2);
- ret_val = xmlNewProp(node, (const xmlChar *)name, (const xmlChar *)value);
+ ret_val = xmlNewProp(node, name, value);
desret_xmlAttrPtr(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_value, value, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewProp",
@@ -21472,9 +22048,9 @@ test_xmlNewReference(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDoc * doc; /* the document */
+ const xmlDoc * doc; /* the target document (optional) */
int n_doc;
- xmlChar * name; /* the reference name, or the reference string with & and ; */
+ const xmlChar * name; /* the entity name */
int n_name;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
@@ -21483,11 +22059,11 @@ test_xmlNewReference(void) {
doc = gen_const_xmlDoc_ptr(n_doc, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlNewReference((const xmlDoc *)doc, (const xmlChar *)name);
+ ret_val = xmlNewReference(doc, name);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewReference",
@@ -21511,17 +22087,17 @@ test_xmlNewText(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlChar * content; /* the text content */
+ const xmlChar * content; /* raw text content (optional) */
int n_content;
for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
mem_base = xmlMemBlocks();
content = gen_const_xmlChar_ptr(n_content, 0);
- ret_val = xmlNewText((const xmlChar *)content);
+ ret_val = xmlNewText(content);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 0);
+ des_const_xmlChar_ptr(n_content, content, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewText",
@@ -21547,11 +22123,11 @@ test_xmlNewTextChild(void) {
xmlNodePtr ret_val;
xmlNodePtr parent; /* the parent node */
int n_parent;
- xmlNsPtr ns; /* a namespace if any */
+ xmlNsPtr ns; /* a namespace (optional) */
int n_ns;
- xmlChar * name; /* the name of the child */
+ const xmlChar * name; /* the name of the child */
int n_name;
- xmlChar * content; /* the text content of the child if any. */
+ const xmlChar * content; /* raw text content of the child (optional) */
int n_content;
for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
@@ -21564,13 +22140,13 @@ test_xmlNewTextChild(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
content = gen_const_xmlChar_ptr(n_content, 3);
- ret_val = xmlNewTextChild(parent, ns, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlNewTextChild(parent, ns, name, content);
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlNodePtr(n_parent, parent, 0);
des_xmlNsPtr(n_ns, ns, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_content, content, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNewTextChild",
@@ -21600,9 +22176,9 @@ test_xmlNewTextLen(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlChar * content; /* the text content */
+ const xmlChar * content; /* raw text content (optional) */
int n_content;
- int len; /* the text len. */
+ int len; /* size of text content */
int n_len;
for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
@@ -21614,10 +22190,10 @@ test_xmlNewTextLen(void) {
(len > xmlStrlen(BAD_CAST content)))
len = 0;
- ret_val = xmlNewTextLen((const xmlChar *)content, len);
+ ret_val = xmlNewTextLen(content, len);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 0);
+ des_const_xmlChar_ptr(n_content, content, 0);
des_int(n_len, len, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -21675,9 +22251,10 @@ test_xmlNodeAddContent(void) {
int test_ret = 0;
int mem_base;
+ int ret_val;
xmlNodePtr cur; /* the node being modified */
int n_cur;
- xmlChar * content; /* extra content */
+ const xmlChar * content; /* extra content */
int n_content;
for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
@@ -21686,10 +22263,11 @@ test_xmlNodeAddContent(void) {
cur = gen_xmlNodePtr(n_cur, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- xmlNodeAddContent(cur, (const xmlChar *)content);
+ ret_val = xmlNodeAddContent(cur, content);
+ desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_cur, cur, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeAddContent",
@@ -21712,9 +22290,10 @@ test_xmlNodeAddContentLen(void) {
int test_ret = 0;
int mem_base;
+ int ret_val;
xmlNodePtr cur; /* the node being modified */
int n_cur;
- xmlChar * content; /* extra content */
+ const xmlChar * content; /* extra content */
int n_content;
int len; /* the size of @content */
int n_len;
@@ -21730,10 +22309,11 @@ test_xmlNodeAddContentLen(void) {
(len > xmlStrlen(BAD_CAST content)))
len = 0;
- xmlNodeAddContentLen(cur, (const xmlChar *)content, len);
+ ret_val = xmlNodeAddContentLen(cur, content, len);
+ desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_cur, cur, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -21762,7 +22342,7 @@ test_xmlNodeBufGetContent(void) {
int ret_val;
xmlBufferPtr buffer; /* a buffer */
int n_buffer;
- xmlNode * cur; /* the node being read */
+ const xmlNode * cur; /* the node being read */
int n_cur;
for (n_buffer = 0;n_buffer < gen_nb_xmlBufferPtr;n_buffer++) {
@@ -21771,11 +22351,11 @@ test_xmlNodeBufGetContent(void) {
buffer = gen_xmlBufferPtr(n_buffer, 0);
cur = gen_const_xmlNode_ptr(n_cur, 1);
- ret_val = xmlNodeBufGetContent(buffer, (const xmlNode *)cur);
+ ret_val = xmlNodeBufGetContent(buffer, cur);
desret_int(ret_val);
call_tests++;
des_xmlBufferPtr(n_buffer, buffer, 0);
- des_const_xmlNode_ptr(n_cur, (const xmlNode *)cur, 1);
+ des_const_xmlNode_ptr(n_cur, cur, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeBufGetContent",
@@ -21871,7 +22451,7 @@ test_xmlNodeDumpOutput(void) {
int n_level;
int format; /* is formatting allowed */
int n_format;
- char * encoding; /* an optional encoding string */
+ const char * encoding; /* an optional encoding string */
int n_encoding;
for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
@@ -21888,14 +22468,14 @@ test_xmlNodeDumpOutput(void) {
format = gen_int(n_format, 4);
encoding = gen_const_char_ptr(n_encoding, 5);
- xmlNodeDumpOutput(buf, doc, cur, level, format, (const char *)encoding);
+ xmlNodeDumpOutput(buf, doc, cur, level, format, encoding);
call_tests++;
des_xmlOutputBufferPtr(n_buf, buf, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlNodePtr(n_cur, cur, 2);
des_int(n_level, level, 3);
des_int(n_format, format, 4);
- des_const_char_ptr(n_encoding, (const char *)encoding, 5);
+ des_const_char_ptr(n_encoding, encoding, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeDumpOutput",
@@ -21922,15 +22502,68 @@ test_xmlNodeDumpOutput(void) {
}
+static int
+test_xmlNodeGetAttrValue(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ const xmlNode * node; /* the node */
+ int n_node;
+ const xmlChar * name; /* the attribute name */
+ int n_name;
+ const xmlChar * nsUri; /* the URI of the namespace */
+ int n_nsUri;
+ xmlChar ** out; /* the returned string */
+ int n_out;
+
+ for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
+ for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+ for (n_nsUri = 0;n_nsUri < gen_nb_const_xmlChar_ptr;n_nsUri++) {
+ for (n_out = 0;n_out < gen_nb_xmlChar_ptr_ptr;n_out++) {
+ mem_base = xmlMemBlocks();
+ node = gen_const_xmlNode_ptr(n_node, 0);
+ name = gen_const_xmlChar_ptr(n_name, 1);
+ nsUri = gen_const_xmlChar_ptr(n_nsUri, 2);
+ out = gen_xmlChar_ptr_ptr(n_out, 3);
+
+ ret_val = xmlNodeGetAttrValue(node, name, nsUri, out);
+ desret_int(ret_val);
+ call_tests++;
+ des_const_xmlNode_ptr(n_node, node, 0);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_nsUri, nsUri, 2);
+ des_xmlChar_ptr_ptr(n_out, out, 3);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlNodeGetAttrValue",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_node);
+ printf(" %d", n_name);
+ printf(" %d", n_nsUri);
+ printf(" %d", n_out);
+ printf("\n");
+ }
+ }
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlNodeGetBase(void) {
int test_ret = 0;
int mem_base;
xmlChar * ret_val;
- xmlDoc * doc; /* the document the node pertains to */
+ const xmlDoc * doc; /* the document the node pertains to */
int n_doc;
- xmlNode * cur; /* the node being checked */
+ const xmlNode * cur; /* the node being checked */
int n_cur;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
@@ -21939,11 +22572,11 @@ test_xmlNodeGetBase(void) {
doc = gen_const_xmlDoc_ptr(n_doc, 0);
cur = gen_const_xmlNode_ptr(n_cur, 1);
- ret_val = xmlNodeGetBase((const xmlDoc *)doc, (const xmlNode *)cur);
+ ret_val = xmlNodeGetBase(doc, cur);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
- des_const_xmlNode_ptr(n_cur, (const xmlNode *)cur, 1);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
+ des_const_xmlNode_ptr(n_cur, cur, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeGetBase",
@@ -21961,23 +22594,69 @@ test_xmlNodeGetBase(void) {
}
+static int
+test_xmlNodeGetBaseSafe(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ const xmlDoc * doc; /* the document the node pertains to */
+ int n_doc;
+ const xmlNode * cur; /* the node being checked */
+ int n_cur;
+ xmlChar ** baseOut; /* pointer to base */
+ int n_baseOut;
+
+ for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
+ for (n_cur = 0;n_cur < gen_nb_const_xmlNode_ptr;n_cur++) {
+ for (n_baseOut = 0;n_baseOut < gen_nb_xmlChar_ptr_ptr;n_baseOut++) {
+ mem_base = xmlMemBlocks();
+ doc = gen_const_xmlDoc_ptr(n_doc, 0);
+ cur = gen_const_xmlNode_ptr(n_cur, 1);
+ baseOut = gen_xmlChar_ptr_ptr(n_baseOut, 2);
+
+ ret_val = xmlNodeGetBaseSafe(doc, cur, baseOut);
+ desret_int(ret_val);
+ call_tests++;
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
+ des_const_xmlNode_ptr(n_cur, cur, 1);
+ des_xmlChar_ptr_ptr(n_baseOut, baseOut, 2);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlNodeGetBaseSafe",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_doc);
+ printf(" %d", n_cur);
+ printf(" %d", n_baseOut);
+ printf("\n");
+ }
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlNodeGetContent(void) {
int test_ret = 0;
int mem_base;
xmlChar * ret_val;
- xmlNode * cur; /* the node being read */
+ const xmlNode * cur; /* the node being read */
int n_cur;
for (n_cur = 0;n_cur < gen_nb_const_xmlNode_ptr;n_cur++) {
mem_base = xmlMemBlocks();
cur = gen_const_xmlNode_ptr(n_cur, 0);
- ret_val = xmlNodeGetContent((const xmlNode *)cur);
+ ret_val = xmlNodeGetContent(cur);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_cur, (const xmlNode *)cur, 0);
+ des_const_xmlNode_ptr(n_cur, cur, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeGetContent",
@@ -21999,17 +22678,17 @@ test_xmlNodeGetLang(void) {
int mem_base;
xmlChar * ret_val;
- xmlNode * cur; /* the node being checked */
+ const xmlNode * cur; /* the node being checked */
int n_cur;
for (n_cur = 0;n_cur < gen_nb_const_xmlNode_ptr;n_cur++) {
mem_base = xmlMemBlocks();
cur = gen_const_xmlNode_ptr(n_cur, 0);
- ret_val = xmlNodeGetLang((const xmlNode *)cur);
+ ret_val = xmlNodeGetLang(cur);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_cur, (const xmlNode *)cur, 0);
+ des_const_xmlNode_ptr(n_cur, cur, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeGetLang",
@@ -22031,17 +22710,17 @@ test_xmlNodeGetSpacePreserve(void) {
int mem_base;
int ret_val;
- xmlNode * cur; /* the node being checked */
+ const xmlNode * cur; /* the node being checked */
int n_cur;
for (n_cur = 0;n_cur < gen_nb_const_xmlNode_ptr;n_cur++) {
mem_base = xmlMemBlocks();
cur = gen_const_xmlNode_ptr(n_cur, 0);
- ret_val = xmlNodeGetSpacePreserve((const xmlNode *)cur);
+ ret_val = xmlNodeGetSpacePreserve(cur);
desret_int(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_cur, (const xmlNode *)cur, 0);
+ des_const_xmlNode_ptr(n_cur, cur, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeGetSpacePreserve",
@@ -22063,17 +22742,17 @@ test_xmlNodeIsText(void) {
int mem_base;
int ret_val;
- xmlNode * node; /* the node */
+ const xmlNode * node; /* the node */
int n_node;
for (n_node = 0;n_node < gen_nb_const_xmlNode_ptr;n_node++) {
mem_base = xmlMemBlocks();
node = gen_const_xmlNode_ptr(n_node, 0);
- ret_val = xmlNodeIsText((const xmlNode *)node);
+ ret_val = xmlNodeIsText(node);
desret_int(ret_val);
call_tests++;
- des_const_xmlNode_ptr(n_node, (const xmlNode *)node, 0);
+ des_const_xmlNode_ptr(n_node, node, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeIsText",
@@ -22096,11 +22775,11 @@ test_xmlNodeListGetRawString(void) {
#if defined(LIBXML_TREE_ENABLED)
int mem_base;
xmlChar * ret_val;
- xmlDoc * doc; /* the document */
+ const xmlDoc * doc; /* a document (optional) */
int n_doc;
- xmlNode * list; /* a Node list */
+ const xmlNode * list; /* a node list of attribute children (optional) */
int n_list;
- int inLine; /* should we replace entity contents or show their external form */
+ int inLine; /* whether entity references are substituted */
int n_inLine;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
@@ -22111,11 +22790,11 @@ test_xmlNodeListGetRawString(void) {
list = gen_const_xmlNode_ptr(n_list, 1);
inLine = gen_int(n_inLine, 2);
- ret_val = xmlNodeListGetRawString((const xmlDoc *)doc, (const xmlNode *)list, inLine);
+ ret_val = xmlNodeListGetRawString(doc, list, inLine);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
- des_const_xmlNode_ptr(n_list, (const xmlNode *)list, 1);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
+ des_const_xmlNode_ptr(n_list, list, 1);
des_int(n_inLine, inLine, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -22143,11 +22822,11 @@ test_xmlNodeListGetString(void) {
int mem_base;
xmlChar * ret_val;
- xmlDocPtr doc; /* the document */
+ xmlDocPtr doc; /* a document (optional) */
int n_doc;
- xmlNode * list; /* a Node list */
+ const xmlNode * list; /* a node list of attribute children (optional) */
int n_list;
- int inLine; /* should we replace entity contents or show their external form */
+ int inLine; /* whether entity references are substituted */
int n_inLine;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -22158,11 +22837,11 @@ test_xmlNodeListGetString(void) {
list = gen_const_xmlNode_ptr(n_list, 1);
inLine = gen_int(n_inLine, 2);
- ret_val = xmlNodeListGetString(doc, (const xmlNode *)list, inLine);
+ ret_val = xmlNodeListGetString(doc, list, inLine);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlNode_ptr(n_list, (const xmlNode *)list, 1);
+ des_const_xmlNode_ptr(n_list, list, 1);
des_int(n_inLine, inLine, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -22189,9 +22868,10 @@ test_xmlNodeSetBase(void) {
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
int mem_base;
+ int ret_val;
xmlNodePtr cur; /* the node being changed */
int n_cur;
- xmlChar * uri; /* the new base URI */
+ const xmlChar * uri; /* the new base URI */
int n_uri;
for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
@@ -22200,10 +22880,11 @@ test_xmlNodeSetBase(void) {
cur = gen_xmlNodePtr(n_cur, 0);
uri = gen_const_xmlChar_ptr(n_uri, 1);
- xmlNodeSetBase(cur, (const xmlChar *)uri);
+ ret_val = xmlNodeSetBase(cur, uri);
+ desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_cur, cur, 0);
- des_const_xmlChar_ptr(n_uri, (const xmlChar *)uri, 1);
+ des_const_xmlChar_ptr(n_uri, uri, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeSetBase",
@@ -22227,9 +22908,10 @@ test_xmlNodeSetContent(void) {
int test_ret = 0;
int mem_base;
+ int ret_val;
xmlNodePtr cur; /* the node being modified */
int n_cur;
- xmlChar * content; /* the new value of the content */
+ const xmlChar * content; /* the new value of the content */
int n_content;
for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
@@ -22238,10 +22920,11 @@ test_xmlNodeSetContent(void) {
cur = gen_xmlNodePtr(n_cur, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- xmlNodeSetContent(cur, (const xmlChar *)content);
+ ret_val = xmlNodeSetContent(cur, content);
+ desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_cur, cur, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeSetContent",
@@ -22265,9 +22948,10 @@ test_xmlNodeSetContentLen(void) {
#if defined(LIBXML_TREE_ENABLED)
int mem_base;
+ int ret_val;
xmlNodePtr cur; /* the node being modified */
int n_cur;
- xmlChar * content; /* the new value of the content */
+ const xmlChar * content; /* the new value of the content */
int n_content;
int len; /* the size of @content */
int n_len;
@@ -22283,10 +22967,11 @@ test_xmlNodeSetContentLen(void) {
(len > xmlStrlen(BAD_CAST content)))
len = 0;
- xmlNodeSetContentLen(cur, (const xmlChar *)content, len);
+ ret_val = xmlNodeSetContentLen(cur, content, len);
+ desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_cur, cur, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -22314,9 +22999,10 @@ test_xmlNodeSetLang(void) {
#if defined(LIBXML_TREE_ENABLED)
int mem_base;
+ int ret_val;
xmlNodePtr cur; /* the node being changed */
int n_cur;
- xmlChar * lang; /* the language description */
+ const xmlChar * lang; /* the language description */
int n_lang;
for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
@@ -22325,10 +23011,11 @@ test_xmlNodeSetLang(void) {
cur = gen_xmlNodePtr(n_cur, 0);
lang = gen_const_xmlChar_ptr(n_lang, 1);
- xmlNodeSetLang(cur, (const xmlChar *)lang);
+ ret_val = xmlNodeSetLang(cur, lang);
+ desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_cur, cur, 0);
- des_const_xmlChar_ptr(n_lang, (const xmlChar *)lang, 1);
+ des_const_xmlChar_ptr(n_lang, lang, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeSetLang",
@@ -22355,7 +23042,7 @@ test_xmlNodeSetName(void) {
int mem_base;
xmlNodePtr cur; /* the node being changed */
int n_cur;
- xmlChar * name; /* the new tag name */
+ const xmlChar * name; /* the new tag name */
int n_name;
for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
@@ -22364,10 +23051,10 @@ test_xmlNodeSetName(void) {
cur = gen_xmlNodePtr(n_cur, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- xmlNodeSetName(cur, (const xmlChar *)name);
+ xmlNodeSetName(cur, name);
call_tests++;
des_xmlNodePtr(n_cur, cur, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNodeSetName",
@@ -22392,6 +23079,7 @@ test_xmlNodeSetSpacePreserve(void) {
#if defined(LIBXML_TREE_ENABLED)
int mem_base;
+ int ret_val;
xmlNodePtr cur; /* the node being changed */
int n_cur;
int val; /* the xml:space value ("0": default, 1: "preserve") */
@@ -22403,7 +23091,8 @@ test_xmlNodeSetSpacePreserve(void) {
cur = gen_xmlNodePtr(n_cur, 0);
val = gen_int(n_val, 1);
- xmlNodeSetSpacePreserve(cur, val);
+ ret_val = xmlNodeSetSpacePreserve(cur, val);
+ desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_cur, cur, 0);
des_int(n_val, val, 1);
@@ -22554,7 +23243,7 @@ test_xmlReplaceNode(void) {
xmlNodePtr ret_val;
xmlNodePtr old; /* the old node */
int n_old;
- xmlNodePtr cur; /* the node */
+ xmlNodePtr cur; /* the node (optional) */
int n_cur;
for (n_old = 0;n_old < gen_nb_xmlNodePtr;n_old++) {
@@ -22645,7 +23334,7 @@ test_xmlSaveFileEnc(void) {
int n_filename;
xmlDocPtr cur; /* the document */
int n_cur;
- char * encoding; /* the name of an encoding (or NULL) */
+ const char * encoding; /* the name of an encoding (or NULL) */
int n_encoding;
for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
@@ -22656,12 +23345,12 @@ test_xmlSaveFileEnc(void) {
cur = gen_xmlDocPtr(n_cur, 1);
encoding = gen_const_char_ptr(n_encoding, 2);
- ret_val = xmlSaveFileEnc(filename, cur, (const char *)encoding);
+ ret_val = xmlSaveFileEnc(filename, cur, encoding);
desret_int(ret_val);
call_tests++;
des_fileoutput(n_filename, filename, 0);
des_xmlDocPtr(n_cur, cur, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSaveFileEnc",
@@ -22693,7 +23382,7 @@ test_xmlSaveFileTo(void) {
int n_buf;
xmlDocPtr cur; /* the document */
int n_cur;
- char * encoding; /* the encoding if any assuming the I/O layer handles the transcoding */
+ const char * encoding; /* the encoding if any assuming the I/O layer handles the transcoding */
int n_encoding;
for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
@@ -22704,13 +23393,13 @@ test_xmlSaveFileTo(void) {
cur = gen_xmlDocPtr(n_cur, 1);
encoding = gen_const_char_ptr(n_encoding, 2);
- ret_val = xmlSaveFileTo(buf, cur, (const char *)encoding);
+ ret_val = xmlSaveFileTo(buf, cur, encoding);
buf = NULL;
desret_int(ret_val);
call_tests++;
des_xmlOutputBufferPtr(n_buf, buf, 0);
des_xmlDocPtr(n_cur, cur, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSaveFileTo",
@@ -22790,7 +23479,7 @@ test_xmlSaveFormatFileEnc(void) {
int n_filename;
xmlDocPtr cur; /* the document being saved */
int n_cur;
- char * encoding; /* the name of the encoding to use or NULL. */
+ const char * encoding; /* the name of the encoding to use or NULL. */
int n_encoding;
int format; /* should formatting spaces be added. */
int n_format;
@@ -22805,12 +23494,12 @@ test_xmlSaveFormatFileEnc(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
format = gen_int(n_format, 3);
- ret_val = xmlSaveFormatFileEnc(filename, cur, (const char *)encoding, format);
+ ret_val = xmlSaveFormatFileEnc(filename, cur, encoding, format);
desret_int(ret_val);
call_tests++;
des_fileoutput(n_filename, filename, 0);
des_xmlDocPtr(n_cur, cur, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_int(n_format, format, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -22845,7 +23534,7 @@ test_xmlSaveFormatFileTo(void) {
int n_buf;
xmlDocPtr cur; /* the document */
int n_cur;
- char * encoding; /* the encoding if any assuming the I/O layer handles the transcoding */
+ const char * encoding; /* the encoding if any assuming the I/O layer handles the transcoding */
int n_encoding;
int format; /* should formatting spaces been added */
int n_format;
@@ -22860,13 +23549,13 @@ test_xmlSaveFormatFileTo(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
format = gen_int(n_format, 3);
- ret_val = xmlSaveFormatFileTo(buf, cur, (const char *)encoding, format);
+ ret_val = xmlSaveFormatFileTo(buf, cur, encoding, format);
buf = NULL;
desret_int(ret_val);
call_tests++;
des_xmlOutputBufferPtr(n_buf, buf, 0);
des_xmlDocPtr(n_cur, cur, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_int(n_format, format, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -22900,7 +23589,7 @@ test_xmlSearchNs(void) {
int n_doc;
xmlNodePtr node; /* the current node */
int n_node;
- xmlChar * nameSpace; /* the namespace prefix */
+ const xmlChar * nameSpace; /* the namespace prefix */
int n_nameSpace;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -22911,12 +23600,12 @@ test_xmlSearchNs(void) {
node = gen_xmlNodePtr(n_node, 1);
nameSpace = gen_const_xmlChar_ptr(n_nameSpace, 2);
- ret_val = xmlSearchNs(doc, node, (const xmlChar *)nameSpace);
+ ret_val = xmlSearchNs(doc, node, nameSpace);
desret_xmlNsPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
des_xmlNodePtr(n_node, node, 1);
- des_const_xmlChar_ptr(n_nameSpace, (const xmlChar *)nameSpace, 2);
+ des_const_xmlChar_ptr(n_nameSpace, nameSpace, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSearchNs",
@@ -22946,7 +23635,7 @@ test_xmlSearchNsByHref(void) {
int n_doc;
xmlNodePtr node; /* the current node */
int n_node;
- xmlChar * href; /* the namespace value */
+ const xmlChar * href; /* the namespace value */
int n_href;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -22957,12 +23646,12 @@ test_xmlSearchNsByHref(void) {
node = gen_xmlNodePtr(n_node, 1);
href = gen_const_xmlChar_ptr(n_href, 2);
- ret_val = xmlSearchNsByHref(doc, node, (const xmlChar *)href);
+ ret_val = xmlSearchNsByHref(doc, node, href);
desret_xmlNsPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
des_xmlNodePtr(n_node, node, 1);
- des_const_xmlChar_ptr(n_href, (const xmlChar *)href, 2);
+ des_const_xmlChar_ptr(n_href, href, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSearchNsByHref",
@@ -23086,7 +23775,7 @@ test_xmlSetNs(void) {
int mem_base;
xmlNodePtr node; /* a node in the document */
int n_node;
- xmlNsPtr ns; /* a namespace pointer */
+ xmlNsPtr ns; /* a namespace pointer (optional) */
int n_ns;
for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
@@ -23127,9 +23816,9 @@ test_xmlSetNsProp(void) {
int n_node;
xmlNsPtr ns; /* the namespace definition */
int n_ns;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
- xmlChar * value; /* the attribute value */
+ const xmlChar * value; /* the attribute value */
int n_value;
for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
@@ -23142,13 +23831,13 @@ test_xmlSetNsProp(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
value = gen_const_xmlChar_ptr(n_value, 3);
- ret_val = xmlSetNsProp(node, ns, (const xmlChar *)name, (const xmlChar *)value);
+ ret_val = xmlSetNsProp(node, ns, name, value);
desret_xmlAttrPtr(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
des_xmlNsPtr(n_ns, ns, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_value, value, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSetNsProp",
@@ -23180,9 +23869,9 @@ test_xmlSetProp(void) {
xmlAttrPtr ret_val;
xmlNodePtr node; /* the node */
int n_node;
- xmlChar * name; /* the attribute name (a QName) */
+ const xmlChar * name; /* the attribute name (a QName) */
int n_name;
- xmlChar * value; /* the attribute value */
+ const xmlChar * value; /* the attribute value */
int n_value;
for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
@@ -23193,12 +23882,12 @@ test_xmlSetProp(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
value = gen_const_xmlChar_ptr(n_value, 2);
- ret_val = xmlSetProp(node, (const xmlChar *)name, (const xmlChar *)value);
+ ret_val = xmlSetProp(node, name, value);
desret_xmlAttrPtr(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_value, value, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSetProp",
@@ -23225,7 +23914,7 @@ test_xmlSplitQName2(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * name; /* the full QName */
+ const xmlChar * name; /* the full QName */
int n_name;
xmlChar ** prefix; /* a xmlChar ** */
int n_prefix;
@@ -23236,10 +23925,10 @@ test_xmlSplitQName2(void) {
name = gen_const_xmlChar_ptr(n_name, 0);
prefix = gen_xmlChar_ptr_ptr(n_prefix, 1);
- ret_val = xmlSplitQName2((const xmlChar *)name, prefix);
+ ret_val = xmlSplitQName2(name, prefix);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+ des_const_xmlChar_ptr(n_name, name, 0);
des_xmlChar_ptr_ptr(n_prefix, prefix, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -23264,7 +23953,7 @@ test_xmlSplitQName3(void) {
int mem_base;
const xmlChar * ret_val;
- xmlChar * name; /* the full QName */
+ const xmlChar * name; /* the full QName */
int n_name;
int * len; /* an int * */
int n_len;
@@ -23275,10 +23964,10 @@ test_xmlSplitQName3(void) {
name = gen_const_xmlChar_ptr(n_name, 0);
len = gen_int_ptr(n_len, 1);
- ret_val = xmlSplitQName3((const xmlChar *)name, len);
+ ret_val = xmlSplitQName3(name, len);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+ des_const_xmlChar_ptr(n_name, name, 0);
des_int_ptr(n_len, len, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -23303,9 +23992,9 @@ test_xmlStringGetNodeList(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDoc * doc; /* the document */
+ const xmlDoc * doc; /* a document (optional) */
int n_doc;
- xmlChar * value; /* the value of the attribute */
+ const xmlChar * value; /* an attribute value */
int n_value;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
@@ -23314,11 +24003,11 @@ test_xmlStringGetNodeList(void) {
doc = gen_const_xmlDoc_ptr(n_doc, 0);
value = gen_const_xmlChar_ptr(n_value, 1);
- ret_val = xmlStringGetNodeList((const xmlDoc *)doc, (const xmlChar *)value);
+ ret_val = xmlStringGetNodeList(doc, value);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
+ des_const_xmlChar_ptr(n_value, value, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStringGetNodeList",
@@ -23342,11 +24031,11 @@ test_xmlStringLenGetNodeList(void) {
int mem_base;
xmlNodePtr ret_val;
- xmlDoc * doc; /* the document */
+ const xmlDoc * doc; /* a document (optional) */
int n_doc;
- xmlChar * value; /* the value of the text */
+ const xmlChar * value; /* an attribute value */
int n_value;
- int len; /* the length of the string value */
+ int len; /* maximum length of the attribute value */
int n_len;
for (n_doc = 0;n_doc < gen_nb_const_xmlDoc_ptr;n_doc++) {
@@ -23360,11 +24049,11 @@ test_xmlStringLenGetNodeList(void) {
(len > xmlStrlen(BAD_CAST value)))
len = 0;
- ret_val = xmlStringLenGetNodeList((const xmlDoc *)doc, (const xmlChar *)value, len);
+ ret_val = xmlStringLenGetNodeList(doc, value, len);
desret_xmlNodePtr(ret_val);
call_tests++;
- des_const_xmlDoc_ptr(n_doc, (const xmlDoc *)doc, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlDoc_ptr(n_doc, doc, 0);
+ des_const_xmlChar_ptr(n_value, value, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -23393,7 +24082,7 @@ test_xmlTextConcat(void) {
int ret_val;
xmlNodePtr node; /* the node */
int n_node;
- xmlChar * content; /* the content */
+ const xmlChar * content; /* the content */
int n_content;
int len; /* @content length */
int n_len;
@@ -23409,11 +24098,11 @@ test_xmlTextConcat(void) {
(len > xmlStrlen(BAD_CAST content)))
len = 0;
- ret_val = xmlTextConcat(node, (const xmlChar *)content, len);
+ ret_val = xmlTextConcat(node, content, len);
desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -23452,9 +24141,10 @@ test_xmlTextMerge(void) {
second = gen_xmlNodePtr_in(n_second, 1);
ret_val = xmlTextMerge(first, second);
- if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
+ if (ret_val == NULL) {
xmlUnlinkNode(second);
- xmlFreeNode(second) ; second = NULL ; }
+ xmlFreeNode(second) ; second = NULL ;
+ ret_val = first; }
desret_xmlNodePtr(ret_val);
call_tests++;
des_xmlNodePtr_in(n_first, first, 0);
@@ -23571,7 +24261,7 @@ test_xmlUnsetNsProp(void) {
int n_node;
xmlNsPtr ns; /* the namespace definition */
int n_ns;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
@@ -23582,12 +24272,12 @@ test_xmlUnsetNsProp(void) {
ns = gen_xmlNsPtr(n_ns, 1);
name = gen_const_xmlChar_ptr(n_name, 2);
- ret_val = xmlUnsetNsProp(node, ns, (const xmlChar *)name);
+ ret_val = xmlUnsetNsProp(node, ns, name);
desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
des_xmlNsPtr(n_ns, ns, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+ des_const_xmlChar_ptr(n_name, name, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlUnsetNsProp",
@@ -23617,7 +24307,7 @@ test_xmlUnsetProp(void) {
int ret_val;
xmlNodePtr node; /* the node */
int n_node;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
@@ -23626,11 +24316,11 @@ test_xmlUnsetProp(void) {
node = gen_xmlNodePtr(n_node, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlUnsetProp(node, (const xmlChar *)name);
+ ret_val = xmlUnsetProp(node, name);
desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlUnsetProp",
@@ -23656,7 +24346,7 @@ test_xmlValidateNCName(void) {
#ifdef LIBXML_TREE_ENABLED
int mem_base;
int ret_val;
- xmlChar * value; /* the value to check */
+ const xmlChar * value; /* the value to check */
int n_value;
int space; /* allow spaces in front and end of the string */
int n_space;
@@ -23667,10 +24357,10 @@ test_xmlValidateNCName(void) {
value = gen_const_xmlChar_ptr(n_value, 0);
space = gen_int(n_space, 1);
- ret_val = xmlValidateNCName((const xmlChar *)value, space);
+ ret_val = xmlValidateNCName(value, space);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
des_int(n_space, space, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -23698,7 +24388,7 @@ test_xmlValidateNMToken(void) {
#ifdef LIBXML_TREE_ENABLED
int mem_base;
int ret_val;
- xmlChar * value; /* the value to check */
+ const xmlChar * value; /* the value to check */
int n_value;
int space; /* allow spaces in front and end of the string */
int n_space;
@@ -23709,10 +24399,10 @@ test_xmlValidateNMToken(void) {
value = gen_const_xmlChar_ptr(n_value, 0);
space = gen_int(n_space, 1);
- ret_val = xmlValidateNMToken((const xmlChar *)value, space);
+ ret_val = xmlValidateNMToken(value, space);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
des_int(n_space, space, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -23741,7 +24431,7 @@ test_xmlValidateName(void) {
#ifdef LIBXML_TREE_ENABLED
int mem_base;
int ret_val;
- xmlChar * value; /* the value to check */
+ const xmlChar * value; /* the value to check */
int n_value;
int space; /* allow spaces in front and end of the string */
int n_space;
@@ -23752,10 +24442,10 @@ test_xmlValidateName(void) {
value = gen_const_xmlChar_ptr(n_value, 0);
space = gen_int(n_space, 1);
- ret_val = xmlValidateName((const xmlChar *)value, space);
+ ret_val = xmlValidateName(value, space);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
des_int(n_space, space, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -23784,7 +24474,7 @@ test_xmlValidateQName(void) {
#ifdef LIBXML_TREE_ENABLED
int mem_base;
int ret_val;
- xmlChar * value; /* the value to check */
+ const xmlChar * value; /* the value to check */
int n_value;
int space; /* allow spaces in front and end of the string */
int n_space;
@@ -23795,10 +24485,10 @@ test_xmlValidateQName(void) {
value = gen_const_xmlChar_ptr(n_value, 0);
space = gen_int(n_space, 1);
- ret_val = xmlValidateQName((const xmlChar *)value, space);
+ ret_val = xmlValidateQName(value, space);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
des_int(n_space, space, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -23822,7 +24512,7 @@ static int
test_tree(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing tree : 144 of 170 functions ...\n");
+ if (quiet == 0) printf("Testing tree : 146 of 173 functions ...\n");
test_ret += test_xmlAddChild();
test_ret += test_xmlAddChildList();
test_ret += test_xmlAddNextSibling();
@@ -23891,6 +24581,7 @@ test_tree(void) {
test_ret += test_xmlGetNoNsProp();
test_ret += test_xmlGetNodePath();
test_ret += test_xmlGetNsList();
+ test_ret += test_xmlGetNsListSafe();
test_ret += test_xmlGetNsProp();
test_ret += test_xmlGetProp();
test_ret += test_xmlHasNsProp();
@@ -23930,7 +24621,9 @@ test_tree(void) {
test_ret += test_xmlNodeBufGetContent();
test_ret += test_xmlNodeDump();
test_ret += test_xmlNodeDumpOutput();
+ test_ret += test_xmlNodeGetAttrValue();
test_ret += test_xmlNodeGetBase();
+ test_ret += test_xmlNodeGetBaseSafe();
test_ret += test_xmlNodeGetContent();
test_ret += test_xmlNodeGetLang();
test_ret += test_xmlNodeGetSpacePreserve();
@@ -23990,9 +24683,9 @@ test_xmlBuildRelativeURI(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * URI; /* the URI reference under consideration */
+ const xmlChar * URI; /* the URI reference under consideration */
int n_URI;
- xmlChar * base; /* the base value */
+ const xmlChar * base; /* the base value */
int n_base;
for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
@@ -24001,11 +24694,11 @@ test_xmlBuildRelativeURI(void) {
URI = gen_const_xmlChar_ptr(n_URI, 0);
base = gen_const_xmlChar_ptr(n_base, 1);
- ret_val = xmlBuildRelativeURI((const xmlChar *)URI, (const xmlChar *)base);
+ ret_val = xmlBuildRelativeURI(URI, base);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
- des_const_xmlChar_ptr(n_base, (const xmlChar *)base, 1);
+ des_const_xmlChar_ptr(n_URI, URI, 0);
+ des_const_xmlChar_ptr(n_base, base, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBuildRelativeURI",
@@ -24023,15 +24716,61 @@ test_xmlBuildRelativeURI(void) {
}
+static int
+test_xmlBuildRelativeURISafe(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ const xmlChar * URI; /* the URI reference under consideration */
+ int n_URI;
+ const xmlChar * base; /* the base value */
+ int n_base;
+ xmlChar ** valPtr; /* pointer to result URI */
+ int n_valPtr;
+
+ for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+ for (n_base = 0;n_base < gen_nb_const_xmlChar_ptr;n_base++) {
+ for (n_valPtr = 0;n_valPtr < gen_nb_xmlChar_ptr_ptr;n_valPtr++) {
+ mem_base = xmlMemBlocks();
+ URI = gen_const_xmlChar_ptr(n_URI, 0);
+ base = gen_const_xmlChar_ptr(n_base, 1);
+ valPtr = gen_xmlChar_ptr_ptr(n_valPtr, 2);
+
+ ret_val = xmlBuildRelativeURISafe(URI, base, valPtr);
+ desret_int(ret_val);
+ call_tests++;
+ des_const_xmlChar_ptr(n_URI, URI, 0);
+ des_const_xmlChar_ptr(n_base, base, 1);
+ des_xmlChar_ptr_ptr(n_valPtr, valPtr, 2);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlBuildRelativeURISafe",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_URI);
+ printf(" %d", n_base);
+ printf(" %d", n_valPtr);
+ printf("\n");
+ }
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlBuildURI(void) {
int test_ret = 0;
int mem_base;
xmlChar * ret_val;
- xmlChar * URI; /* the URI instance found in the document */
+ const xmlChar * URI; /* the URI instance found in the document */
int n_URI;
- xmlChar * base; /* the base value */
+ const xmlChar * base; /* the base value */
int n_base;
for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
@@ -24040,11 +24779,11 @@ test_xmlBuildURI(void) {
URI = gen_const_xmlChar_ptr(n_URI, 0);
base = gen_const_xmlChar_ptr(n_base, 1);
- ret_val = xmlBuildURI((const xmlChar *)URI, (const xmlChar *)base);
+ ret_val = xmlBuildURI(URI, base);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
- des_const_xmlChar_ptr(n_base, (const xmlChar *)base, 1);
+ des_const_xmlChar_ptr(n_URI, URI, 0);
+ des_const_xmlChar_ptr(n_base, base, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlBuildURI",
@@ -24062,23 +24801,69 @@ test_xmlBuildURI(void) {
}
+static int
+test_xmlBuildURISafe(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ const xmlChar * URI; /* the URI instance found in the document */
+ int n_URI;
+ const xmlChar * base; /* the base value */
+ int n_base;
+ xmlChar ** valPtr; /* pointer to result URI */
+ int n_valPtr;
+
+ for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+ for (n_base = 0;n_base < gen_nb_const_xmlChar_ptr;n_base++) {
+ for (n_valPtr = 0;n_valPtr < gen_nb_xmlChar_ptr_ptr;n_valPtr++) {
+ mem_base = xmlMemBlocks();
+ URI = gen_const_xmlChar_ptr(n_URI, 0);
+ base = gen_const_xmlChar_ptr(n_base, 1);
+ valPtr = gen_xmlChar_ptr_ptr(n_valPtr, 2);
+
+ ret_val = xmlBuildURISafe(URI, base, valPtr);
+ desret_int(ret_val);
+ call_tests++;
+ des_const_xmlChar_ptr(n_URI, URI, 0);
+ des_const_xmlChar_ptr(n_base, base, 1);
+ des_xmlChar_ptr_ptr(n_valPtr, valPtr, 2);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlBuildURISafe",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_URI);
+ printf(" %d", n_base);
+ printf(" %d", n_valPtr);
+ printf("\n");
+ }
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlCanonicPath(void) {
int test_ret = 0;
int mem_base;
xmlChar * ret_val;
- xmlChar * path; /* the resource locator in a filesystem notation */
+ const xmlChar * path; /* the resource locator in a filesystem notation */
int n_path;
for (n_path = 0;n_path < gen_nb_const_xmlChar_ptr;n_path++) {
mem_base = xmlMemBlocks();
path = gen_const_xmlChar_ptr(n_path, 0);
- ret_val = xmlCanonicPath((const xmlChar *)path);
+ ret_val = xmlCanonicPath(path);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_path, (const xmlChar *)path, 0);
+ des_const_xmlChar_ptr(n_path, path, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCanonicPath",
@@ -24168,7 +24953,7 @@ test_xmlParseURIReference(void) {
int ret_val;
xmlURIPtr uri; /* pointer to an URI structure */
int n_uri;
- char * str; /* the string to analyze */
+ const char * str; /* the string to analyze */
int n_str;
for (n_uri = 0;n_uri < gen_nb_xmlURIPtr;n_uri++) {
@@ -24177,11 +24962,11 @@ test_xmlParseURIReference(void) {
uri = gen_xmlURIPtr(n_uri, 0);
str = gen_const_char_ptr(n_str, 1);
- ret_val = xmlParseURIReference(uri, (const char *)str);
+ ret_val = xmlParseURIReference(uri, str);
desret_int(ret_val);
call_tests++;
des_xmlURIPtr(n_uri, uri, 0);
- des_const_char_ptr(n_str, (const char *)str, 1);
+ des_const_char_ptr(n_str, str, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParseURIReference",
@@ -24199,23 +24984,66 @@ test_xmlParseURIReference(void) {
}
+#define gen_nb_xmlURIPtr_ptr 1
+#define gen_xmlURIPtr_ptr(no, nr) NULL
+#define des_xmlURIPtr_ptr(no, val, nr)
+
+static int
+test_xmlParseURISafe(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ const char * str; /* the URI string to analyze */
+ int n_str;
+ xmlURIPtr * uriOut; /* optional pointer to parsed URI */
+ int n_uriOut;
+
+ for (n_str = 0;n_str < gen_nb_filepath;n_str++) {
+ for (n_uriOut = 0;n_uriOut < gen_nb_xmlURIPtr_ptr;n_uriOut++) {
+ mem_base = xmlMemBlocks();
+ str = gen_filepath(n_str, 0);
+ uriOut = gen_xmlURIPtr_ptr(n_uriOut, 1);
+
+ ret_val = xmlParseURISafe(str, uriOut);
+ desret_int(ret_val);
+ call_tests++;
+ des_filepath(n_str, str, 0);
+ des_xmlURIPtr_ptr(n_uriOut, uriOut, 1);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlParseURISafe",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_str);
+ printf(" %d", n_uriOut);
+ printf("\n");
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlPathToURI(void) {
int test_ret = 0;
int mem_base;
xmlChar * ret_val;
- xmlChar * path; /* the resource locator in a filesystem notation */
+ const xmlChar * path; /* the resource locator in a filesystem notation */
int n_path;
for (n_path = 0;n_path < gen_nb_const_xmlChar_ptr;n_path++) {
mem_base = xmlMemBlocks();
path = gen_const_xmlChar_ptr(n_path, 0);
- ret_val = xmlPathToURI((const xmlChar *)path);
+ ret_val = xmlPathToURI(path);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_path, (const xmlChar *)path, 0);
+ des_const_xmlChar_ptr(n_path, path, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlPathToURI",
@@ -24306,17 +25134,17 @@ test_xmlURIEscape(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * str; /* the string of the URI to escape */
+ const xmlChar * str; /* the string of the URI to escape */
int n_str;
for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
mem_base = xmlMemBlocks();
str = gen_const_xmlChar_ptr(n_str, 0);
- ret_val = xmlURIEscape((const xmlChar *)str);
+ ret_val = xmlURIEscape(str);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+ des_const_xmlChar_ptr(n_str, str, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlURIEscape",
@@ -24338,9 +25166,9 @@ test_xmlURIEscapeStr(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * str; /* string to escape */
+ const xmlChar * str; /* string to escape */
int n_str;
- xmlChar * list; /* exception list string of chars not to escape */
+ const xmlChar * list; /* exception list string of chars not to escape */
int n_list;
for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
@@ -24349,11 +25177,11 @@ test_xmlURIEscapeStr(void) {
str = gen_const_xmlChar_ptr(n_str, 0);
list = gen_const_xmlChar_ptr(n_list, 1);
- ret_val = xmlURIEscapeStr((const xmlChar *)str, (const xmlChar *)list);
+ ret_val = xmlURIEscapeStr(str, list);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
- des_const_xmlChar_ptr(n_list, (const xmlChar *)list, 1);
+ des_const_xmlChar_ptr(n_str, str, 0);
+ des_const_xmlChar_ptr(n_list, list, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlURIEscapeStr",
@@ -24384,15 +25212,18 @@ static int
test_uri(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing uri : 10 of 15 functions ...\n");
+ if (quiet == 0) printf("Testing uri : 13 of 18 functions ...\n");
test_ret += test_xmlBuildRelativeURI();
+ test_ret += test_xmlBuildRelativeURISafe();
test_ret += test_xmlBuildURI();
+ test_ret += test_xmlBuildURISafe();
test_ret += test_xmlCanonicPath();
test_ret += test_xmlCreateURI();
test_ret += test_xmlNormalizeURIPath();
test_ret += test_xmlParseURI();
test_ret += test_xmlParseURIRaw();
test_ret += test_xmlParseURIReference();
+ test_ret += test_xmlParseURISafe();
test_ret += test_xmlPathToURI();
test_ret += test_xmlPrintURI();
test_ret += test_xmlSaveUri();
@@ -24415,17 +25246,17 @@ test_xmlAddAttributeDecl(void) {
int n_ctxt;
xmlDtdPtr dtd; /* pointer to the DTD */
int n_dtd;
- xmlChar * elem; /* the element name */
+ const xmlChar * elem; /* the element name */
int n_elem;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
- xmlChar * ns; /* the attribute namespace prefix */
+ const xmlChar * ns; /* the attribute namespace prefix */
int n_ns;
xmlAttributeType type; /* the attribute type */
int n_type;
xmlAttributeDefault def; /* the attribute default type */
int n_def;
- xmlChar * defaultValue; /* the attribute default value */
+ const xmlChar * defaultValue; /* the attribute default value */
int n_defaultValue;
xmlEnumerationPtr tree; /* if it's an enumeration, the associated list */
int n_tree;
@@ -24450,17 +25281,17 @@ test_xmlAddAttributeDecl(void) {
defaultValue = gen_const_xmlChar_ptr(n_defaultValue, 7);
tree = gen_xmlEnumerationPtr(n_tree, 8);
- ret_val = xmlAddAttributeDecl(ctxt, dtd, (const xmlChar *)elem, (const xmlChar *)name, (const xmlChar *)ns, type, def, (const xmlChar *)defaultValue, tree);
+ ret_val = xmlAddAttributeDecl(ctxt, dtd, elem, name, ns, type, def, defaultValue, tree);
desret_xmlAttributePtr(ret_val);
call_tests++;
des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
des_xmlDtdPtr(n_dtd, dtd, 1);
- des_const_xmlChar_ptr(n_elem, (const xmlChar *)elem, 2);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 3);
- des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 4);
+ des_const_xmlChar_ptr(n_elem, elem, 2);
+ des_const_xmlChar_ptr(n_name, name, 3);
+ des_const_xmlChar_ptr(n_ns, ns, 4);
des_xmlAttributeType(n_type, type, 5);
des_xmlAttributeDefault(n_def, def, 6);
- des_const_xmlChar_ptr(n_defaultValue, (const xmlChar *)defaultValue, 7);
+ des_const_xmlChar_ptr(n_defaultValue, defaultValue, 7);
des_xmlEnumerationPtr(n_tree, tree, 8);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -24503,7 +25334,7 @@ test_xmlAddElementDecl(void) {
int n_ctxt;
xmlDtdPtr dtd; /* pointer to the DTD */
int n_dtd;
- xmlChar * name; /* the entity name */
+ const xmlChar * name; /* the entity name */
int n_name;
xmlElementTypeVal type; /* the element type */
int n_type;
@@ -24522,12 +25353,12 @@ test_xmlAddElementDecl(void) {
type = gen_xmlElementTypeVal(n_type, 3);
content = gen_xmlElementContentPtr(n_content, 4);
- ret_val = xmlAddElementDecl(ctxt, dtd, (const xmlChar *)name, type, content);
+ ret_val = xmlAddElementDecl(ctxt, dtd, name, type, content);
desret_xmlElementPtr(ret_val);
call_tests++;
des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
des_xmlDtdPtr(n_dtd, dtd, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+ des_const_xmlChar_ptr(n_name, name, 2);
des_xmlElementTypeVal(n_type, type, 3);
des_xmlElementContentPtr(n_content, content, 4);
xmlResetLastError();
@@ -24563,6 +25394,45 @@ test_xmlAddID(void) {
}
+static int
+test_xmlAddIDSafe(void) {
+ int test_ret = 0;
+
+ int mem_base;
+ int ret_val;
+ xmlAttrPtr attr; /* the attribute holding the ID */
+ int n_attr;
+ const xmlChar * value; /* the attribute (ID) value */
+ int n_value;
+
+ for (n_attr = 0;n_attr < gen_nb_xmlAttrPtr;n_attr++) {
+ for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+ mem_base = xmlMemBlocks();
+ attr = gen_xmlAttrPtr(n_attr, 0);
+ value = gen_const_xmlChar_ptr(n_value, 1);
+
+ ret_val = xmlAddIDSafe(attr, value);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlAttrPtr(n_attr, attr, 0);
+ des_const_xmlChar_ptr(n_value, value, 1);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlAddIDSafe",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_attr);
+ printf(" %d", n_value);
+ printf("\n");
+ }
+ }
+ }
+ function_tests++;
+
+ return(test_ret);
+}
+
+
static int
test_xmlAddNotationDecl(void) {
int test_ret = 0;
@@ -24970,9 +25840,9 @@ test_xmlGetDtdAttrDesc(void) {
xmlAttributePtr ret_val;
xmlDtdPtr dtd; /* a pointer to the DtD to search */
int n_dtd;
- xmlChar * elem; /* the element name */
+ const xmlChar * elem; /* the element name */
int n_elem;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
@@ -24983,12 +25853,12 @@ test_xmlGetDtdAttrDesc(void) {
elem = gen_const_xmlChar_ptr(n_elem, 1);
name = gen_const_xmlChar_ptr(n_name, 2);
- ret_val = xmlGetDtdAttrDesc(dtd, (const xmlChar *)elem, (const xmlChar *)name);
+ ret_val = xmlGetDtdAttrDesc(dtd, elem, name);
desret_xmlAttributePtr(ret_val);
call_tests++;
des_xmlDtdPtr(n_dtd, dtd, 0);
- des_const_xmlChar_ptr(n_elem, (const xmlChar *)elem, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+ des_const_xmlChar_ptr(n_elem, elem, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetDtdAttrDesc",
@@ -25016,7 +25886,7 @@ test_xmlGetDtdElementDesc(void) {
xmlElementPtr ret_val;
xmlDtdPtr dtd; /* a pointer to the DtD to search */
int n_dtd;
- xmlChar * name; /* the element name */
+ const xmlChar * name; /* the element name */
int n_name;
for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
@@ -25025,11 +25895,11 @@ test_xmlGetDtdElementDesc(void) {
dtd = gen_xmlDtdPtr(n_dtd, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlGetDtdElementDesc(dtd, (const xmlChar *)name);
+ ret_val = xmlGetDtdElementDesc(dtd, name);
desret_xmlElementPtr(ret_val);
call_tests++;
des_xmlDtdPtr(n_dtd, dtd, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetDtdElementDesc",
@@ -25065,11 +25935,11 @@ test_xmlGetDtdQAttrDesc(void) {
xmlAttributePtr ret_val;
xmlDtdPtr dtd; /* a pointer to the DtD to search */
int n_dtd;
- xmlChar * elem; /* the element name */
+ const xmlChar * elem; /* the element name */
int n_elem;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
- xmlChar * prefix; /* the attribute namespace prefix */
+ const xmlChar * prefix; /* the attribute namespace prefix */
int n_prefix;
for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
@@ -25082,13 +25952,13 @@ test_xmlGetDtdQAttrDesc(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
prefix = gen_const_xmlChar_ptr(n_prefix, 3);
- ret_val = xmlGetDtdQAttrDesc(dtd, (const xmlChar *)elem, (const xmlChar *)name, (const xmlChar *)prefix);
+ ret_val = xmlGetDtdQAttrDesc(dtd, elem, name, prefix);
desret_xmlAttributePtr(ret_val);
call_tests++;
des_xmlDtdPtr(n_dtd, dtd, 0);
- des_const_xmlChar_ptr(n_elem, (const xmlChar *)elem, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 3);
+ des_const_xmlChar_ptr(n_elem, elem, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_prefix, prefix, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetDtdQAttrDesc",
@@ -25118,9 +25988,9 @@ test_xmlGetDtdQElementDesc(void) {
xmlElementPtr ret_val;
xmlDtdPtr dtd; /* a pointer to the DtD to search */
int n_dtd;
- xmlChar * name; /* the element name */
+ const xmlChar * name; /* the element name */
int n_name;
- xmlChar * prefix; /* the element namespace prefix */
+ const xmlChar * prefix; /* the element namespace prefix */
int n_prefix;
for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
@@ -25131,12 +26001,12 @@ test_xmlGetDtdQElementDesc(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
prefix = gen_const_xmlChar_ptr(n_prefix, 2);
- ret_val = xmlGetDtdQElementDesc(dtd, (const xmlChar *)name, (const xmlChar *)prefix);
+ ret_val = xmlGetDtdQElementDesc(dtd, name, prefix);
desret_xmlElementPtr(ret_val);
call_tests++;
des_xmlDtdPtr(n_dtd, dtd, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_prefix, prefix, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetDtdQElementDesc",
@@ -25164,7 +26034,7 @@ test_xmlGetID(void) {
xmlAttrPtr ret_val;
xmlDocPtr doc; /* pointer to the document */
int n_doc;
- xmlChar * ID; /* the ID value */
+ const xmlChar * ID; /* the ID value */
int n_ID;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -25173,11 +26043,11 @@ test_xmlGetID(void) {
doc = gen_xmlDocPtr(n_doc, 0);
ID = gen_const_xmlChar_ptr(n_ID, 1);
- ret_val = xmlGetID(doc, (const xmlChar *)ID);
+ ret_val = xmlGetID(doc, ID);
desret_xmlAttrPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_ID, (const xmlChar *)ID, 1);
+ des_const_xmlChar_ptr(n_ID, ID, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlGetID",
@@ -25259,7 +26129,7 @@ test_xmlIsMixedElement(void) {
int ret_val;
xmlDocPtr doc; /* the document */
int n_doc;
- xmlChar * name; /* the element name */
+ const xmlChar * name; /* the element name */
int n_name;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -25268,11 +26138,11 @@ test_xmlIsMixedElement(void) {
doc = gen_xmlDocPtr(n_doc, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlIsMixedElement(doc, (const xmlChar *)name);
+ ret_val = xmlIsMixedElement(doc, name);
desret_int(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlIsMixedElement",
@@ -25344,7 +26214,7 @@ test_xmlNewDocElementContent(void) {
xmlElementContentPtr ret_val;
xmlDocPtr doc; /* the document */
int n_doc;
- xmlChar * name; /* the subelement name or NULL */
+ const xmlChar * name; /* the subelement name or NULL */
int n_name;
xmlElementContentType type; /* the type of element content decl */
int n_type;
@@ -25357,12 +26227,12 @@ test_xmlNewDocElementContent(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
type = gen_xmlElementContentType(n_type, 2);
- ret_val = xmlNewDocElementContent(doc, (const xmlChar *)name, type);
+ ret_val = xmlNewDocElementContent(doc, name, type);
xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;
desret_xmlElementContentPtr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_xmlElementContentType(n_type, type, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -25389,7 +26259,7 @@ test_xmlNewElementContent(void) {
int mem_base;
xmlElementContentPtr ret_val;
- xmlChar * name; /* the subelement name or NULL */
+ const xmlChar * name; /* the subelement name or NULL */
int n_name;
xmlElementContentType type; /* the type of element content decl */
int n_type;
@@ -25400,10 +26270,10 @@ test_xmlNewElementContent(void) {
name = gen_const_xmlChar_ptr(n_name, 0);
type = gen_xmlElementContentType(n_type, 1);
- ret_val = xmlNewElementContent((const xmlChar *)name, type);
+ ret_val = xmlNewElementContent(name, type);
desret_xmlElementContentPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+ des_const_xmlChar_ptr(n_name, name, 0);
des_xmlElementContentType(n_type, type, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -25663,9 +26533,9 @@ test_xmlValidCtxtNormalizeAttributeValue(void) {
int n_doc;
xmlNodePtr elem; /* the parent */
int n_elem;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
- xmlChar * value; /* the attribute value */
+ const xmlChar * value; /* the attribute value */
int n_value;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
@@ -25680,14 +26550,14 @@ test_xmlValidCtxtNormalizeAttributeValue(void) {
name = gen_const_xmlChar_ptr(n_name, 3);
value = gen_const_xmlChar_ptr(n_value, 4);
- ret_val = xmlValidCtxtNormalizeAttributeValue(ctxt, doc, elem, (const xmlChar *)name, (const xmlChar *)value);
+ ret_val = xmlValidCtxtNormalizeAttributeValue(ctxt, doc, elem, name, value);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlNodePtr(n_elem, elem, 2);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 3);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 4);
+ des_const_xmlChar_ptr(n_name, name, 3);
+ des_const_xmlChar_ptr(n_value, value, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidCtxtNormalizeAttributeValue",
@@ -25726,7 +26596,7 @@ test_xmlValidGetPotentialChildren(void) {
int ret_val;
xmlElementContent * ctree; /* an element content tree */
int n_ctree;
- xmlChar ** names; /* an array to store the list of child names */
+ const xmlChar ** names; /* an array to store the list of child names */
int n_names;
int * len; /* a pointer to the number of element in the list */
int n_len;
@@ -25743,11 +26613,11 @@ test_xmlValidGetPotentialChildren(void) {
len = gen_int_ptr(n_len, 2);
max = gen_int(n_max, 3);
- ret_val = xmlValidGetPotentialChildren(ctree, (const xmlChar **)names, len, max);
+ ret_val = xmlValidGetPotentialChildren(ctree, names, len, max);
desret_int(ret_val);
call_tests++;
des_xmlElementContent_ptr(n_ctree, ctree, 0);
- des_const_xmlChar_ptr_ptr(n_names, (const xmlChar **)names, 1);
+ des_const_xmlChar_ptr_ptr(n_names, names, 1);
des_int_ptr(n_len, len, 2);
des_int(n_max, max, 3);
xmlResetLastError();
@@ -25785,7 +26655,7 @@ test_xmlValidGetValidElements(void) {
int n_prev;
xmlNode * next; /* an element to insert next */
int n_next;
- xmlChar ** names; /* an array to store the list of child names */
+ const xmlChar ** names; /* an array to store the list of child names */
int n_names;
int max; /* the size of the array */
int n_max;
@@ -25800,12 +26670,12 @@ test_xmlValidGetValidElements(void) {
names = gen_const_xmlChar_ptr_ptr(n_names, 2);
max = gen_int(n_max, 3);
- ret_val = xmlValidGetValidElements(prev, next, (const xmlChar **)names, max);
+ ret_val = xmlValidGetValidElements(prev, next, names, max);
desret_int(ret_val);
call_tests++;
des_xmlNodePtr(n_prev, prev, 0);
des_xmlNodePtr(n_next, next, 1);
- des_const_xmlChar_ptr_ptr(n_names, (const xmlChar **)names, 2);
+ des_const_xmlChar_ptr_ptr(n_names, names, 2);
des_int(n_max, max, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -25841,9 +26711,9 @@ test_xmlValidNormalizeAttributeValue(void) {
int n_doc;
xmlNodePtr elem; /* the parent */
int n_elem;
- xmlChar * name; /* the attribute name */
+ const xmlChar * name; /* the attribute name */
int n_name;
- xmlChar * value; /* the attribute value */
+ const xmlChar * value; /* the attribute value */
int n_value;
for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -25856,13 +26726,13 @@ test_xmlValidNormalizeAttributeValue(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
value = gen_const_xmlChar_ptr(n_value, 3);
- ret_val = xmlValidNormalizeAttributeValue(doc, elem, (const xmlChar *)name, (const xmlChar *)value);
+ ret_val = xmlValidNormalizeAttributeValue(doc, elem, name, value);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlDocPtr(n_doc, doc, 0);
des_xmlNodePtr(n_elem, elem, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_value, value, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidNormalizeAttributeValue",
@@ -25942,7 +26812,7 @@ test_xmlValidateAttributeValue(void) {
int ret_val;
xmlAttributeType type; /* an attribute type */
int n_type;
- xmlChar * value; /* an attribute value */
+ const xmlChar * value; /* an attribute value */
int n_value;
for (n_type = 0;n_type < gen_nb_xmlAttributeType;n_type++) {
@@ -25951,11 +26821,11 @@ test_xmlValidateAttributeValue(void) {
type = gen_xmlAttributeType(n_type, 0);
value = gen_const_xmlChar_ptr(n_value, 1);
- ret_val = xmlValidateAttributeValue(type, (const xmlChar *)value);
+ ret_val = xmlValidateAttributeValue(type, value);
desret_int(ret_val);
call_tests++;
des_xmlAttributeType(n_type, type, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidateAttributeValue",
@@ -26248,17 +27118,17 @@ test_xmlValidateNameValue(void) {
#if defined(LIBXML_VALID_ENABLED)
int mem_base;
int ret_val;
- xmlChar * value; /* an Name value */
+ const xmlChar * value; /* an Name value */
int n_value;
for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
mem_base = xmlMemBlocks();
value = gen_const_xmlChar_ptr(n_value, 0);
- ret_val = xmlValidateNameValue((const xmlChar *)value);
+ ret_val = xmlValidateNameValue(value);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidateNameValue",
@@ -26282,17 +27152,17 @@ test_xmlValidateNamesValue(void) {
#if defined(LIBXML_VALID_ENABLED)
int mem_base;
int ret_val;
- xmlChar * value; /* an Names value */
+ const xmlChar * value; /* an Names value */
int n_value;
for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
mem_base = xmlMemBlocks();
value = gen_const_xmlChar_ptr(n_value, 0);
- ret_val = xmlValidateNamesValue((const xmlChar *)value);
+ ret_val = xmlValidateNamesValue(value);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidateNamesValue",
@@ -26316,17 +27186,17 @@ test_xmlValidateNmtokenValue(void) {
#if defined(LIBXML_VALID_ENABLED)
int mem_base;
int ret_val;
- xmlChar * value; /* an Nmtoken value */
+ const xmlChar * value; /* an Nmtoken value */
int n_value;
for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
mem_base = xmlMemBlocks();
value = gen_const_xmlChar_ptr(n_value, 0);
- ret_val = xmlValidateNmtokenValue((const xmlChar *)value);
+ ret_val = xmlValidateNmtokenValue(value);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidateNmtokenValue",
@@ -26350,17 +27220,17 @@ test_xmlValidateNmtokensValue(void) {
#if defined(LIBXML_VALID_ENABLED)
int mem_base;
int ret_val;
- xmlChar * value; /* an Nmtokens value */
+ const xmlChar * value; /* an Nmtokens value */
int n_value;
for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
mem_base = xmlMemBlocks();
value = gen_const_xmlChar_ptr(n_value, 0);
- ret_val = xmlValidateNmtokensValue((const xmlChar *)value);
+ ret_val = xmlValidateNmtokensValue(value);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidateNmtokensValue",
@@ -26436,7 +27306,7 @@ test_xmlValidateNotationUse(void) {
int n_ctxt;
xmlDocPtr doc; /* the document */
int n_doc;
- xmlChar * notationName; /* the notation name to check */
+ const xmlChar * notationName; /* the notation name to check */
int n_notationName;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
@@ -26447,12 +27317,12 @@ test_xmlValidateNotationUse(void) {
doc = gen_xmlDocPtr(n_doc, 1);
notationName = gen_const_xmlChar_ptr(n_notationName, 2);
- ret_val = xmlValidateNotationUse(ctxt, doc, (const xmlChar *)notationName);
+ ret_val = xmlValidateNotationUse(ctxt, doc, notationName);
desret_int(ret_val);
call_tests++;
des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
des_xmlDocPtr(n_doc, doc, 1);
- des_const_xmlChar_ptr(n_notationName, (const xmlChar *)notationName, 2);
+ des_const_xmlChar_ptr(n_notationName, notationName, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidateNotationUse",
@@ -26488,7 +27358,7 @@ test_xmlValidateOneAttribute(void) {
int n_elem;
xmlAttrPtr attr; /* an attribute instance */
int n_attr;
- xmlChar * value; /* the attribute value (without entities processing) */
+ const xmlChar * value; /* the attribute value (without entities processing) */
int n_value;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
@@ -26503,14 +27373,14 @@ test_xmlValidateOneAttribute(void) {
attr = gen_xmlAttrPtr(n_attr, 3);
value = gen_const_xmlChar_ptr(n_value, 4);
- ret_val = xmlValidateOneAttribute(ctxt, doc, elem, attr, (const xmlChar *)value);
+ ret_val = xmlValidateOneAttribute(ctxt, doc, elem, attr, value);
desret_int(ret_val);
call_tests++;
des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlNodePtr(n_elem, elem, 2);
des_xmlAttrPtr(n_attr, attr, 3);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 4);
+ des_const_xmlChar_ptr(n_value, value, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidateOneAttribute",
@@ -26596,11 +27466,11 @@ test_xmlValidateOneNamespace(void) {
int n_doc;
xmlNodePtr elem; /* an element instance */
int n_elem;
- xmlChar * prefix; /* the namespace prefix */
+ const xmlChar * prefix; /* the namespace prefix */
int n_prefix;
xmlNsPtr ns; /* an namespace declaration instance */
int n_ns;
- xmlChar * value; /* the attribute value (without entities processing) */
+ const xmlChar * value; /* the attribute value (without entities processing) */
int n_value;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
@@ -26617,15 +27487,15 @@ test_xmlValidateOneNamespace(void) {
ns = gen_xmlNsPtr(n_ns, 4);
value = gen_const_xmlChar_ptr(n_value, 5);
- ret_val = xmlValidateOneNamespace(ctxt, doc, elem, (const xmlChar *)prefix, ns, (const xmlChar *)value);
+ ret_val = xmlValidateOneNamespace(ctxt, doc, elem, prefix, ns, value);
desret_int(ret_val);
call_tests++;
des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlNodePtr(n_elem, elem, 2);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 3);
+ des_const_xmlChar_ptr(n_prefix, prefix, 3);
des_xmlNsPtr(n_ns, ns, 4);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 5);
+ des_const_xmlChar_ptr(n_value, value, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidateOneNamespace",
@@ -26665,7 +27535,7 @@ test_xmlValidatePopElement(void) {
int n_doc;
xmlNodePtr elem; /* an element instance */
int n_elem;
- xmlChar * qname; /* the qualified name as appearing in the serialization */
+ const xmlChar * qname; /* the qualified name as appearing in the serialization */
int n_qname;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
@@ -26678,13 +27548,13 @@ test_xmlValidatePopElement(void) {
elem = gen_xmlNodePtr(n_elem, 2);
qname = gen_const_xmlChar_ptr(n_qname, 3);
- ret_val = xmlValidatePopElement(ctxt, doc, elem, (const xmlChar *)qname);
+ ret_val = xmlValidatePopElement(ctxt, doc, elem, qname);
desret_int(ret_val);
call_tests++;
des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlNodePtr(n_elem, elem, 2);
- des_const_xmlChar_ptr(n_qname, (const xmlChar *)qname, 3);
+ des_const_xmlChar_ptr(n_qname, qname, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidatePopElement",
@@ -26716,7 +27586,7 @@ test_xmlValidatePushCData(void) {
int ret_val;
xmlValidCtxtPtr ctxt; /* the validation context */
int n_ctxt;
- xmlChar * data; /* some character data read */
+ const xmlChar * data; /* some character data read */
int n_data;
int len; /* the length of the data */
int n_len;
@@ -26732,11 +27602,11 @@ test_xmlValidatePushCData(void) {
(len > xmlStrlen(BAD_CAST data)))
len = 0;
- ret_val = xmlValidatePushCData(ctxt, (const xmlChar *)data, len);
+ ret_val = xmlValidatePushCData(ctxt, data, len);
desret_int(ret_val);
call_tests++;
des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_data, (const xmlChar *)data, 1);
+ des_const_xmlChar_ptr(n_data, data, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -26771,7 +27641,7 @@ test_xmlValidatePushElement(void) {
int n_doc;
xmlNodePtr elem; /* an element instance */
int n_elem;
- xmlChar * qname; /* the qualified name as appearing in the serialization */
+ const xmlChar * qname; /* the qualified name as appearing in the serialization */
int n_qname;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
@@ -26784,13 +27654,13 @@ test_xmlValidatePushElement(void) {
elem = gen_xmlNodePtr(n_elem, 2);
qname = gen_const_xmlChar_ptr(n_qname, 3);
- ret_val = xmlValidatePushElement(ctxt, doc, elem, (const xmlChar *)qname);
+ ret_val = xmlValidatePushElement(ctxt, doc, elem, qname);
desret_int(ret_val);
call_tests++;
des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
des_xmlDocPtr(n_doc, doc, 1);
des_xmlNodePtr(n_elem, elem, 2);
- des_const_xmlChar_ptr(n_qname, (const xmlChar *)qname, 3);
+ des_const_xmlChar_ptr(n_qname, qname, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlValidatePushElement",
@@ -26857,10 +27727,11 @@ static int
test_valid(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing valid : 50 of 70 functions ...\n");
+ if (quiet == 0) printf("Testing valid : 51 of 71 functions ...\n");
test_ret += test_xmlAddAttributeDecl();
test_ret += test_xmlAddElementDecl();
test_ret += test_xmlAddID();
+ test_ret += test_xmlAddIDSafe();
test_ret += test_xmlAddNotationDecl();
test_ret += test_xmlAddRef();
test_ret += test_xmlCopyAttributeTable();
@@ -26924,6 +27795,47 @@ test_valid(void) {
printf("Module valid: %d errors\n", test_ret);
return(test_ret);
}
+#ifdef LIBXML_XINCLUDE_ENABLED
+
+#define gen_nb_xmlXIncludeCtxtPtr 1
+#define gen_xmlXIncludeCtxtPtr(no, nr) NULL
+#define des_xmlXIncludeCtxtPtr(no, val, nr)
+#endif
+
+
+static int
+test_xmlXIncludeGetLastError(void) {
+ int test_ret = 0;
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+ int mem_base;
+ int ret_val;
+ xmlXIncludeCtxtPtr ctxt; /* an XInclude processing context */
+ int n_ctxt;
+
+ for (n_ctxt = 0;n_ctxt < gen_nb_xmlXIncludeCtxtPtr;n_ctxt++) {
+ mem_base = xmlMemBlocks();
+ ctxt = gen_xmlXIncludeCtxtPtr(n_ctxt, 0);
+
+ ret_val = xmlXIncludeGetLastError(ctxt);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlXIncludeCtxtPtr(n_ctxt, ctxt, 0);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlXIncludeGetLastError",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_ctxt);
+ printf("\n");
+ }
+ }
+ function_tests++;
+#endif
+
+ return(test_ret);
+}
+
static int
test_xmlXIncludeNewContext(void) {
@@ -27057,13 +27969,6 @@ test_xmlXIncludeProcessFlagsData(void) {
return(test_ret);
}
-#ifdef LIBXML_XINCLUDE_ENABLED
-
-#define gen_nb_xmlXIncludeCtxtPtr 1
-#define gen_xmlXIncludeCtxtPtr(no, nr) NULL
-#define des_xmlXIncludeCtxtPtr(no, val, nr)
-#endif
-
static int
test_xmlXIncludeProcessNode(void) {
@@ -27229,6 +28134,16 @@ test_xmlXIncludeProcessTreeFlagsData(void) {
}
+static int
+test_xmlXIncludeSetErrorHandler(void) {
+ int test_ret = 0;
+
+
+ /* missing type support */
+ return(test_ret);
+}
+
+
static int
test_xmlXIncludeSetFlags(void) {
int test_ret = 0;
@@ -27273,7 +28188,8 @@ static int
test_xinclude(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing xinclude : 8 of 10 functions ...\n");
+ if (quiet == 0) printf("Testing xinclude : 9 of 12 functions ...\n");
+ test_ret += test_xmlXIncludeGetLastError();
test_ret += test_xmlXIncludeNewContext();
test_ret += test_xmlXIncludeProcess();
test_ret += test_xmlXIncludeProcessFlags();
@@ -27282,6 +28198,7 @@ test_xinclude(void) {
test_ret += test_xmlXIncludeProcessTree();
test_ret += test_xmlXIncludeProcessTreeFlags();
test_ret += test_xmlXIncludeProcessTreeFlagsData();
+ test_ret += test_xmlXIncludeSetErrorHandler();
test_ret += test_xmlXIncludeSetFlags();
if (test_ret != 0)
@@ -27329,7 +28246,7 @@ test_xmlAllocParserInputBuffer(void) {
int mem_base;
xmlParserInputBufferPtr ret_val;
- xmlCharEncoding enc; /* the charset encoding if known */
+ xmlCharEncoding enc; /* the charset encoding if known (deprecated) */
int n_enc;
for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
@@ -27361,17 +28278,17 @@ test_xmlCheckFilename(void) {
int mem_base;
int ret_val;
- char * path; /* the path to check */
+ const char * path; /* the path to check */
int n_path;
for (n_path = 0;n_path < gen_nb_const_char_ptr;n_path++) {
mem_base = xmlMemBlocks();
path = gen_const_char_ptr(n_path, 0);
- ret_val = xmlCheckFilename((const char *)path);
+ ret_val = xmlCheckFilename(path);
desret_int(ret_val);
call_tests++;
- des_const_char_ptr(n_path, (const char *)path, 0);
+ des_const_char_ptr(n_path, path, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCheckFilename",
@@ -27924,7 +28841,7 @@ test_xmlNoNetExternalEntityLoader(void) {
xmlParserInputPtr ret_val;
const char * URL; /* the URL for the entity to load */
int n_URL;
- char * ID; /* the System ID for the entity to load */
+ const char * ID; /* the System ID for the entity to load */
int n_ID;
xmlParserCtxtPtr ctxt; /* the context in which the entity is called or NULL */
int n_ctxt;
@@ -27937,11 +28854,11 @@ test_xmlNoNetExternalEntityLoader(void) {
ID = gen_const_char_ptr(n_ID, 1);
ctxt = gen_xmlParserCtxtPtr(n_ctxt, 2);
- ret_val = xmlNoNetExternalEntityLoader(URL, (const char *)ID, ctxt);
+ ret_val = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
desret_xmlParserInputPtr(ret_val);
call_tests++;
des_filepath(n_URL, URL, 0);
- des_const_char_ptr(n_ID, (const char *)ID, 1);
+ des_const_char_ptr(n_ID, ID, 1);
des_xmlParserCtxtPtr(n_ctxt, ctxt, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -27968,17 +28885,17 @@ test_xmlNormalizeWindowsPath(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * path; /* the input file path */
+ const xmlChar * path; /* the input file path */
int n_path;
for (n_path = 0;n_path < gen_nb_const_xmlChar_ptr;n_path++) {
mem_base = xmlMemBlocks();
path = gen_const_xmlChar_ptr(n_path, 0);
- ret_val = xmlNormalizeWindowsPath((const xmlChar *)path);
+ ret_val = xmlNormalizeWindowsPath(path);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_path, (const xmlChar *)path, 0);
+ des_const_xmlChar_ptr(n_path, path, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlNormalizeWindowsPath",
@@ -28264,7 +29181,7 @@ test_xmlOutputBufferWrite(void) {
int n_out;
int len; /* the size in bytes of the array. */
int n_len;
- char * buf; /* an char array */
+ const char * buf; /* an char array */
int n_buf;
for (n_out = 0;n_out < gen_nb_xmlOutputBufferPtr;n_out++) {
@@ -28278,12 +29195,12 @@ test_xmlOutputBufferWrite(void) {
(len > xmlStrlen(BAD_CAST buf)))
len = 0;
- ret_val = xmlOutputBufferWrite(out, len, (const char *)buf);
+ ret_val = xmlOutputBufferWrite(out, len, buf);
desret_int(ret_val);
call_tests++;
des_xmlOutputBufferPtr(n_out, out, 0);
des_int(n_len, len, 1);
- des_const_char_ptr(n_buf, (const char *)buf, 2);
+ des_const_char_ptr(n_buf, buf, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlOutputBufferWrite",
@@ -28323,7 +29240,7 @@ test_xmlOutputBufferWriteString(void) {
int ret_val;
xmlOutputBufferPtr out; /* a buffered parser output */
int n_out;
- char * str; /* a zero terminated C string */
+ const char * str; /* a zero terminated C string */
int n_str;
for (n_out = 0;n_out < gen_nb_xmlOutputBufferPtr;n_out++) {
@@ -28332,11 +29249,11 @@ test_xmlOutputBufferWriteString(void) {
out = gen_xmlOutputBufferPtr(n_out, 0);
str = gen_const_char_ptr(n_str, 1);
- ret_val = xmlOutputBufferWriteString(out, (const char *)str);
+ ret_val = xmlOutputBufferWriteString(out, str);
desret_int(ret_val);
call_tests++;
des_xmlOutputBufferPtr(n_out, out, 0);
- des_const_char_ptr(n_str, (const char *)str, 1);
+ des_const_char_ptr(n_str, str, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlOutputBufferWriteString",
@@ -28373,7 +29290,7 @@ test_xmlParserInputBufferCreateFd(void) {
xmlParserInputBufferPtr ret_val;
int fd; /* a file descriptor number */
int n_fd;
- xmlCharEncoding enc; /* the charset encoding if known */
+ xmlCharEncoding enc; /* the charset encoding if known (deprecated) */
int n_enc;
for (n_fd = 0;n_fd < gen_nb_int;n_fd++) {
@@ -28413,7 +29330,7 @@ test_xmlParserInputBufferCreateFile(void) {
xmlParserInputBufferPtr ret_val;
FILE * file; /* a FILE* */
int n_file;
- xmlCharEncoding enc; /* the charset encoding if known */
+ xmlCharEncoding enc; /* the charset encoding if known (deprecated) */
int n_enc;
for (n_file = 0;n_file < gen_nb_FILE_ptr;n_file++) {
@@ -28499,11 +29416,11 @@ test_xmlParserInputBufferCreateMem(void) {
int mem_base;
xmlParserInputBufferPtr ret_val;
- char * mem; /* the memory input */
+ const char * mem; /* the memory input */
int n_mem;
int size; /* the length of the memory block */
int n_size;
- xmlCharEncoding enc; /* the charset encoding if known */
+ xmlCharEncoding enc; /* the charset encoding if known (deprecated) */
int n_enc;
for (n_mem = 0;n_mem < gen_nb_const_char_ptr;n_mem++) {
@@ -28517,10 +29434,10 @@ test_xmlParserInputBufferCreateMem(void) {
(size > xmlStrlen(BAD_CAST mem)))
size = 0;
- ret_val = xmlParserInputBufferCreateMem((const char *)mem, size, enc);
+ ret_val = xmlParserInputBufferCreateMem(mem, size, enc);
desret_xmlParserInputBufferPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_mem, (const char *)mem, 0);
+ des_const_char_ptr(n_mem, mem, 0);
des_int(n_size, size, 1);
des_xmlCharEncoding(n_enc, enc, 2);
xmlResetLastError();
@@ -28548,7 +29465,7 @@ test_xmlParserInputBufferCreateStatic(void) {
int mem_base;
xmlParserInputBufferPtr ret_val;
- char * mem; /* the memory input */
+ const char * mem; /* the memory input */
int n_mem;
int size; /* the length of the memory block */
int n_size;
@@ -28566,10 +29483,10 @@ test_xmlParserInputBufferCreateStatic(void) {
(size > xmlStrlen(BAD_CAST mem)))
size = 0;
- ret_val = xmlParserInputBufferCreateStatic((const char *)mem, size, enc);
+ ret_val = xmlParserInputBufferCreateStatic(mem, size, enc);
desret_xmlParserInputBufferPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_mem, (const char *)mem, 0);
+ des_const_char_ptr(n_mem, mem, 0);
des_int(n_size, size, 1);
des_xmlCharEncoding(n_enc, enc, 2);
xmlResetLastError();
@@ -28640,7 +29557,7 @@ test_xmlParserInputBufferPush(void) {
int n_in;
int len; /* the size in bytes of the array. */
int n_len;
- char * buf; /* an char array */
+ const char * buf; /* an char array */
int n_buf;
for (n_in = 0;n_in < gen_nb_xmlParserInputBufferPtr;n_in++) {
@@ -28654,12 +29571,12 @@ test_xmlParserInputBufferPush(void) {
(len > xmlStrlen(BAD_CAST buf)))
len = 0;
- ret_val = xmlParserInputBufferPush(in, len, (const char *)buf);
+ ret_val = xmlParserInputBufferPush(in, len, buf);
desret_int(ret_val);
call_tests++;
des_xmlParserInputBufferPtr(n_in, in, 0);
des_int(n_len, len, 1);
- des_const_char_ptr(n_buf, (const char *)buf, 2);
+ des_const_char_ptr(n_buf, buf, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlParserInputBufferPush",
@@ -29284,7 +30201,7 @@ test_xmlCopyError(void) {
int mem_base;
int ret_val;
- xmlError * from; /* a source error */
+ const xmlError * from; /* a source error */
int n_from;
xmlErrorPtr to; /* a target error */
int n_to;
@@ -29295,10 +30212,10 @@ test_xmlCopyError(void) {
from = gen_const_xmlError_ptr(n_from, 0);
to = gen_xmlErrorPtr(n_to, 1);
- ret_val = xmlCopyError((const xmlError *)from, to);
+ ret_val = xmlCopyError(from, to);
desret_int(ret_val);
call_tests++;
- des_const_xmlError_ptr(n_from, (const xmlError *)from, 0);
+ des_const_xmlError_ptr(n_from, from, 0);
des_xmlErrorPtr(n_to, to, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -29357,6 +30274,16 @@ test_xmlCtxtResetLastError(void) {
}
+static int
+test_xmlFormatError(void) {
+ int test_ret = 0;
+
+
+ /* missing type support */
+ return(test_ret);
+}
+
+
static int
test_xmlGetLastError(void) {
int test_ret = 0;
@@ -29555,11 +30482,12 @@ static int
test_xmlerror(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing xmlerror : 7 of 17 functions ...\n");
+ if (quiet == 0) printf("Testing xmlerror : 7 of 18 functions ...\n");
test_ret += test_initGenericErrorDefaultFunc();
test_ret += test_xmlCopyError();
test_ret += test_xmlCtxtGetLastError();
test_ret += test_xmlCtxtResetLastError();
+ test_ret += test_xmlFormatError();
test_ret += test_xmlGetLastError();
test_ret += test_xmlParserError();
test_ret += test_xmlParserPrintFileContext();
@@ -29639,7 +30567,7 @@ test_xmlModuleSymbol(void) {
int ret_val;
xmlModulePtr module; /* the module */
int n_module;
- char * name; /* the name of the symbol */
+ const char * name; /* the name of the symbol */
int n_name;
void ** symbol; /* the resulting symbol address */
int n_symbol;
@@ -29652,11 +30580,11 @@ test_xmlModuleSymbol(void) {
name = gen_const_char_ptr(n_name, 1);
symbol = gen_void_ptr_ptr(n_symbol, 2);
- ret_val = xmlModuleSymbol(module, (const char *)name, symbol);
+ ret_val = xmlModuleSymbol(module, name, symbol);
desret_int(ret_val);
call_tests++;
des_xmlModulePtr(n_module, module, 0);
- des_const_char_ptr(n_name, (const char *)name, 1);
+ des_const_char_ptr(n_name, name, 1);
des_void_ptr_ptr(n_symbol, symbol, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -29773,11 +30701,11 @@ test_xmlReaderForDoc(void) {
#if defined(LIBXML_READER_ENABLED)
int mem_base;
xmlTextReaderPtr ret_val;
- xmlChar * cur; /* a pointer to a zero terminated string */
+ const xmlChar * cur; /* a pointer to a zero terminated string */
int n_cur;
const char * URL; /* the base URL to use for the document */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding, or NULL */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -29792,12 +30720,12 @@ test_xmlReaderForDoc(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
options = gen_parseroptions(n_options, 3);
- ret_val = xmlReaderForDoc((const xmlChar *)cur, URL, (const char *)encoding, options);
+ ret_val = xmlReaderForDoc(cur, URL, encoding, options);
desret_xmlTextReaderPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+ des_const_xmlChar_ptr(n_cur, cur, 0);
des_filepath(n_URL, URL, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_parseroptions(n_options, options, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -29830,7 +30758,7 @@ test_xmlReaderForFile(void) {
xmlTextReaderPtr ret_val;
const char * filename; /* a file or URL */
int n_filename;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding, or NULL */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -29843,11 +30771,11 @@ test_xmlReaderForFile(void) {
encoding = gen_const_char_ptr(n_encoding, 1);
options = gen_parseroptions(n_options, 2);
- ret_val = xmlReaderForFile(filename, (const char *)encoding, options);
+ ret_val = xmlReaderForFile(filename, encoding, options);
desret_xmlTextReaderPtr(ret_val);
call_tests++;
des_filepath(n_filename, filename, 0);
- des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+ des_const_char_ptr(n_encoding, encoding, 1);
des_parseroptions(n_options, options, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -29876,13 +30804,13 @@ test_xmlReaderForMemory(void) {
#if defined(LIBXML_READER_ENABLED)
int mem_base;
xmlTextReaderPtr ret_val;
- char * buffer; /* a pointer to a char array */
+ const char * buffer; /* a pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
const char * URL; /* the base URL to use for the document */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding, or NULL */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -29902,13 +30830,13 @@ test_xmlReaderForMemory(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlReaderForMemory((const char *)buffer, size, URL, (const char *)encoding, options);
+ ret_val = xmlReaderForMemory(buffer, size, URL, encoding, options);
desret_xmlTextReaderPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+ des_const_char_ptr(n_buffer, buffer, 0);
des_int(n_size, size, 1);
des_filepath(n_URL, URL, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_const_char_ptr(n_encoding, encoding, 3);
des_parseroptions(n_options, options, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -29943,11 +30871,11 @@ test_xmlReaderNewDoc(void) {
int ret_val;
xmlTextReaderPtr reader; /* an XML reader */
int n_reader;
- xmlChar * cur; /* a pointer to a zero terminated string */
+ const xmlChar * cur; /* a pointer to a zero terminated string */
int n_cur;
const char * URL; /* the base URL to use for the document */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding, or NULL */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -29964,13 +30892,13 @@ test_xmlReaderNewDoc(void) {
encoding = gen_const_char_ptr(n_encoding, 3);
options = gen_parseroptions(n_options, 4);
- ret_val = xmlReaderNewDoc(reader, (const xmlChar *)cur, URL, (const char *)encoding, options);
+ ret_val = xmlReaderNewDoc(reader, cur, URL, encoding, options);
desret_int(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+ des_const_xmlChar_ptr(n_cur, cur, 1);
des_filepath(n_URL, URL, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_const_char_ptr(n_encoding, encoding, 3);
des_parseroptions(n_options, options, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -30007,7 +30935,7 @@ test_xmlReaderNewFile(void) {
int n_reader;
const char * filename; /* a file or URL */
int n_filename;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding, or NULL */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -30022,12 +30950,12 @@ test_xmlReaderNewFile(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
options = gen_parseroptions(n_options, 3);
- ret_val = xmlReaderNewFile(reader, filename, (const char *)encoding, options);
+ ret_val = xmlReaderNewFile(reader, filename, encoding, options);
desret_int(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
des_filepath(n_filename, filename, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+ des_const_char_ptr(n_encoding, encoding, 2);
des_parseroptions(n_options, options, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -30060,13 +30988,13 @@ test_xmlReaderNewMemory(void) {
int ret_val;
xmlTextReaderPtr reader; /* an XML reader */
int n_reader;
- char * buffer; /* a pointer to a char array */
+ const char * buffer; /* a pointer to a char array */
int n_buffer;
int size; /* the size of the array */
int n_size;
const char * URL; /* the base URL to use for the document */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding, or NULL */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -30088,14 +31016,14 @@ test_xmlReaderNewMemory(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlReaderNewMemory(reader, (const char *)buffer, size, URL, (const char *)encoding, options);
+ ret_val = xmlReaderNewMemory(reader, buffer, size, URL, encoding, options);
desret_int(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+ des_const_char_ptr(n_buffer, buffer, 1);
des_int(n_size, size, 2);
des_filepath(n_URL, URL, 3);
- des_const_char_ptr(n_encoding, (const char *)encoding, 4);
+ des_const_char_ptr(n_encoding, encoding, 4);
des_parseroptions(n_options, options, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -30547,7 +31475,7 @@ test_xmlTextReaderConstString(void) {
const xmlChar * ret_val;
xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
int n_reader;
- xmlChar * str; /* the string to intern. */
+ const xmlChar * str; /* the string to intern. */
int n_str;
for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
@@ -30556,11 +31484,11 @@ test_xmlTextReaderConstString(void) {
reader = gen_xmlTextReaderPtr(n_reader, 0);
str = gen_const_xmlChar_ptr(n_str, 1);
- ret_val = xmlTextReaderConstString(reader, (const xmlChar *)str);
+ ret_val = xmlTextReaderConstString(reader, str);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextReaderConstString",
@@ -30826,7 +31754,7 @@ test_xmlTextReaderGetAttribute(void) {
xmlChar * ret_val;
xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
int n_reader;
- xmlChar * name; /* the qualified name of the attribute. */
+ const xmlChar * name; /* the qualified name of the attribute. */
int n_name;
for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
@@ -30835,11 +31763,11 @@ test_xmlTextReaderGetAttribute(void) {
reader = gen_xmlTextReaderPtr(n_reader, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlTextReaderGetAttribute(reader, (const xmlChar *)name);
+ ret_val = xmlTextReaderGetAttribute(reader, name);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextReaderGetAttribute",
@@ -30908,9 +31836,9 @@ test_xmlTextReaderGetAttributeNs(void) {
xmlChar * ret_val;
xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
int n_reader;
- xmlChar * localName; /* the local name of the attribute. */
+ const xmlChar * localName; /* the local name of the attribute. */
int n_localName;
- xmlChar * namespaceURI; /* the namespace URI of the attribute. */
+ const xmlChar * namespaceURI; /* the namespace URI of the attribute. */
int n_namespaceURI;
for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
@@ -30921,12 +31849,12 @@ test_xmlTextReaderGetAttributeNs(void) {
localName = gen_const_xmlChar_ptr(n_localName, 1);
namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 2);
- ret_val = xmlTextReaderGetAttributeNs(reader, (const xmlChar *)localName, (const xmlChar *)namespaceURI);
+ ret_val = xmlTextReaderGetAttributeNs(reader, localName, namespaceURI);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_xmlChar_ptr(n_localName, (const xmlChar *)localName, 1);
- des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 2);
+ des_const_xmlChar_ptr(n_localName, localName, 1);
+ des_const_xmlChar_ptr(n_namespaceURI, namespaceURI, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextReaderGetAttributeNs",
@@ -31000,6 +31928,16 @@ test_xmlTextReaderGetErrorHandler(void) {
}
+static int
+test_xmlTextReaderGetLastError(void) {
+ int test_ret = 0;
+
+
+ /* missing type support */
+ return(test_ret);
+}
+
+
static int
test_xmlTextReaderGetParserColumnNumber(void) {
int test_ret = 0;
@@ -31465,7 +32403,7 @@ test_xmlTextReaderLookupNamespace(void) {
xmlChar * ret_val;
xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
int n_reader;
- xmlChar * prefix; /* the prefix whose namespace URI is to be resolved. To return the default namespace, specify NULL */
+ const xmlChar * prefix; /* the prefix whose namespace URI is to be resolved. To return the default namespace, specify NULL */
int n_prefix;
for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
@@ -31474,11 +32412,11 @@ test_xmlTextReaderLookupNamespace(void) {
reader = gen_xmlTextReaderPtr(n_reader, 0);
prefix = gen_const_xmlChar_ptr(n_prefix, 1);
- ret_val = xmlTextReaderLookupNamespace(reader, (const xmlChar *)prefix);
+ ret_val = xmlTextReaderLookupNamespace(reader, prefix);
desret_xmlChar_ptr(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextReaderLookupNamespace",
@@ -31506,7 +32444,7 @@ test_xmlTextReaderMoveToAttribute(void) {
int ret_val;
xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
int n_reader;
- xmlChar * name; /* the qualified name of the attribute. */
+ const xmlChar * name; /* the qualified name of the attribute. */
int n_name;
for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
@@ -31515,11 +32453,11 @@ test_xmlTextReaderMoveToAttribute(void) {
reader = gen_xmlTextReaderPtr(n_reader, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlTextReaderMoveToAttribute(reader, (const xmlChar *)name);
+ ret_val = xmlTextReaderMoveToAttribute(reader, name);
desret_int(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextReaderMoveToAttribute",
@@ -31588,9 +32526,9 @@ test_xmlTextReaderMoveToAttributeNs(void) {
int ret_val;
xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
int n_reader;
- xmlChar * localName; /* the local name of the attribute. */
+ const xmlChar * localName; /* the local name of the attribute. */
int n_localName;
- xmlChar * namespaceURI; /* the namespace URI of the attribute. */
+ const xmlChar * namespaceURI; /* the namespace URI of the attribute. */
int n_namespaceURI;
for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
@@ -31601,12 +32539,12 @@ test_xmlTextReaderMoveToAttributeNs(void) {
localName = gen_const_xmlChar_ptr(n_localName, 1);
namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 2);
- ret_val = xmlTextReaderMoveToAttributeNs(reader, (const xmlChar *)localName, (const xmlChar *)namespaceURI);
+ ret_val = xmlTextReaderMoveToAttributeNs(reader, localName, namespaceURI);
desret_int(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_xmlChar_ptr(n_localName, (const xmlChar *)localName, 1);
- des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 2);
+ des_const_xmlChar_ptr(n_localName, localName, 1);
+ des_const_xmlChar_ptr(n_namespaceURI, namespaceURI, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextReaderMoveToAttributeNs",
@@ -32011,9 +32949,9 @@ test_xmlTextReaderPreservePattern(void) {
int ret_val;
xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
int n_reader;
- xmlChar * pattern; /* an XPath subset pattern */
+ const xmlChar * pattern; /* an XPath subset pattern */
int n_pattern;
- xmlChar ** namespaces; /* the prefix definitions, array of [URI, prefix] or NULL */
+ const xmlChar ** namespaces; /* the prefix definitions, array of [URI, prefix] or NULL */
int n_namespaces;
for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
@@ -32024,12 +32962,12 @@ test_xmlTextReaderPreservePattern(void) {
pattern = gen_const_xmlChar_ptr(n_pattern, 1);
namespaces = gen_const_xmlChar_ptr_ptr(n_namespaces, 2);
- ret_val = xmlTextReaderPreservePattern(reader, (const xmlChar *)pattern, (const xmlChar **)namespaces);
+ ret_val = xmlTextReaderPreservePattern(reader, pattern, namespaces);
desret_int(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_xmlChar_ptr(n_pattern, (const xmlChar *)pattern, 1);
- des_const_xmlChar_ptr_ptr(n_namespaces, (const xmlChar **)namespaces, 2);
+ des_const_xmlChar_ptr(n_pattern, pattern, 1);
+ des_const_xmlChar_ptr_ptr(n_namespaces, namespaces, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextReaderPreservePattern",
@@ -32237,7 +33175,7 @@ test_xmlTextReaderRelaxNGValidate(void) {
int ret_val;
xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
int n_reader;
- char * rng; /* the path to a RelaxNG schema or NULL */
+ const char * rng; /* the path to a RelaxNG schema or NULL */
int n_rng;
for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
@@ -32246,11 +33184,11 @@ test_xmlTextReaderRelaxNGValidate(void) {
reader = gen_xmlTextReaderPtr(n_reader, 0);
rng = gen_const_char_ptr(n_rng, 1);
- ret_val = xmlTextReaderRelaxNGValidate(reader, (const char *)rng);
+ ret_val = xmlTextReaderRelaxNGValidate(reader, rng);
desret_int(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_char_ptr(n_rng, (const char *)rng, 1);
+ des_const_char_ptr(n_rng, rng, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextReaderRelaxNGValidate",
@@ -32325,7 +33263,7 @@ test_xmlTextReaderSchemaValidate(void) {
int ret_val;
xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
int n_reader;
- char * xsd; /* the path to a W3C XSD schema or NULL */
+ const char * xsd; /* the path to a W3C XSD schema or NULL */
int n_xsd;
for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
@@ -32333,11 +33271,11 @@ test_xmlTextReaderSchemaValidate(void) {
reader = gen_xmlTextReaderPtr(n_reader, 0);
xsd = gen_const_char_ptr(n_xsd, 1);
- ret_val = xmlTextReaderSchemaValidate(reader, (const char *)xsd);
+ ret_val = xmlTextReaderSchemaValidate(reader, xsd);
desret_int(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
- des_const_char_ptr(n_xsd, (const char *)xsd, 1);
+ des_const_char_ptr(n_xsd, xsd, 1);
xmlResetLastError();
}
}
@@ -32528,7 +33466,7 @@ test_xmlTextReaderSetup(void) {
int n_input;
const char * URL; /* the base URL to use for the document */
int n_URL;
- char * encoding; /* the document encoding, or NULL */
+ const char * encoding; /* the document encoding, or NULL */
int n_encoding;
int options; /* a combination of xmlParserOption */
int n_options;
@@ -32545,12 +33483,12 @@ test_xmlTextReaderSetup(void) {
encoding = gen_const_char_ptr(n_encoding, 3);
options = gen_parseroptions(n_options, 4);
- ret_val = xmlTextReaderSetup(reader, input, URL, (const char *)encoding, options);
+ ret_val = xmlTextReaderSetup(reader, input, URL, encoding, options);
desret_int(ret_val);
call_tests++;
des_xmlTextReaderPtr(n_reader, reader, 0);
des_filepath(n_URL, URL, 2);
- des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+ des_const_char_ptr(n_encoding, encoding, 3);
des_parseroptions(n_options, options, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -32681,7 +33619,7 @@ static int
test_xmlreader(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing xmlreader : 76 of 87 functions ...\n");
+ if (quiet == 0) printf("Testing xmlreader : 76 of 88 functions ...\n");
test_ret += test_xmlNewTextReader();
test_ret += test_xmlNewTextReaderFilename();
test_ret += test_xmlReaderForDoc();
@@ -32714,6 +33652,7 @@ test_xmlreader(void) {
test_ret += test_xmlTextReaderGetAttributeNo();
test_ret += test_xmlTextReaderGetAttributeNs();
test_ret += test_xmlTextReaderGetErrorHandler();
+ test_ret += test_xmlTextReaderGetLastError();
test_ret += test_xmlTextReaderGetParserColumnNumber();
test_ret += test_xmlTextReaderGetParserLineNumber();
test_ret += test_xmlTextReaderGetParserProp();
@@ -32895,7 +33834,7 @@ test_xmlExpGetLanguage(void) {
int n_ctxt;
xmlExpNodePtr exp; /* the expression */
int n_exp;
- xmlChar ** langList; /* where to store the tokens */
+ const xmlChar ** langList; /* where to store the tokens */
int n_langList;
int len; /* the allocated length of @list */
int n_len;
@@ -32910,12 +33849,12 @@ test_xmlExpGetLanguage(void) {
langList = gen_const_xmlChar_ptr_ptr(n_langList, 2);
len = gen_int(n_len, 3);
- ret_val = xmlExpGetLanguage(ctxt, exp, (const xmlChar **)langList, len);
+ ret_val = xmlExpGetLanguage(ctxt, exp, langList, len);
desret_int(ret_val);
call_tests++;
des_xmlExpCtxtPtr(n_ctxt, ctxt, 0);
des_xmlExpNodePtr(n_exp, exp, 1);
- des_const_xmlChar_ptr_ptr(n_langList, (const xmlChar **)langList, 2);
+ des_const_xmlChar_ptr_ptr(n_langList, langList, 2);
des_int(n_len, len, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -32950,7 +33889,7 @@ test_xmlExpGetStart(void) {
int n_ctxt;
xmlExpNodePtr exp; /* the expression */
int n_exp;
- xmlChar ** tokList; /* where to store the tokens */
+ const xmlChar ** tokList; /* where to store the tokens */
int n_tokList;
int len; /* the allocated length of @list */
int n_len;
@@ -32965,12 +33904,12 @@ test_xmlExpGetStart(void) {
tokList = gen_const_xmlChar_ptr_ptr(n_tokList, 2);
len = gen_int(n_len, 3);
- ret_val = xmlExpGetStart(ctxt, exp, (const xmlChar **)tokList, len);
+ ret_val = xmlExpGetStart(ctxt, exp, tokList, len);
desret_int(ret_val);
call_tests++;
des_xmlExpCtxtPtr(n_ctxt, ctxt, 0);
des_xmlExpNodePtr(n_exp, exp, 1);
- des_const_xmlChar_ptr_ptr(n_tokList, (const xmlChar **)tokList, 2);
+ des_const_xmlChar_ptr_ptr(n_tokList, tokList, 2);
des_int(n_len, len, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -33228,7 +34167,7 @@ test_xmlRegExecErrInfo(void) {
int ret_val;
xmlRegExecCtxtPtr exec; /* a regexp execution context generating an error */
int n_exec;
- xmlChar ** string; /* return value for the error string */
+ const xmlChar ** string; /* return value for the error string */
int n_string;
int * nbval; /* pointer to the number of accepted values IN/OUT */
int n_nbval;
@@ -33253,11 +34192,11 @@ test_xmlRegExecErrInfo(void) {
values = gen_xmlChar_ptr_ptr(n_values, 4);
terminal = gen_int_ptr(n_terminal, 5);
- ret_val = xmlRegExecErrInfo(exec, (const xmlChar **)string, nbval, nbneg, values, terminal);
+ ret_val = xmlRegExecErrInfo(exec, string, nbval, nbneg, values, terminal);
desret_int(ret_val);
call_tests++;
des_xmlRegExecCtxtPtr(n_exec, exec, 0);
- des_const_xmlChar_ptr_ptr(n_string, (const xmlChar **)string, 1);
+ des_const_xmlChar_ptr_ptr(n_string, string, 1);
des_int_ptr(n_nbval, nbval, 2);
des_int_ptr(n_nbneg, nbneg, 3);
des_xmlChar_ptr_ptr(n_values, values, 4);
@@ -33359,7 +34298,7 @@ test_xmlRegExecPushString(void) {
int ret_val;
xmlRegExecCtxtPtr exec; /* a regexp execution context or NULL to indicate the end */
int n_exec;
- xmlChar * value; /* a string token input */
+ const xmlChar * value; /* a string token input */
int n_value;
void * data; /* data associated to the token to reuse in callbacks */
int n_data;
@@ -33372,11 +34311,11 @@ test_xmlRegExecPushString(void) {
value = gen_const_xmlChar_ptr(n_value, 1);
data = gen_userdata(n_data, 2);
- ret_val = xmlRegExecPushString(exec, (const xmlChar *)value, data);
+ ret_val = xmlRegExecPushString(exec, value, data);
desret_int(ret_val);
call_tests++;
des_xmlRegExecCtxtPtr(n_exec, exec, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
des_userdata(n_data, data, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -33407,9 +34346,9 @@ test_xmlRegExecPushString2(void) {
int ret_val;
xmlRegExecCtxtPtr exec; /* a regexp execution context or NULL to indicate the end */
int n_exec;
- xmlChar * value; /* the first string token input */
+ const xmlChar * value; /* the first string token input */
int n_value;
- xmlChar * value2; /* the second string token input */
+ const xmlChar * value2; /* the second string token input */
int n_value2;
void * data; /* data associated to the token to reuse in callbacks */
int n_data;
@@ -33424,12 +34363,12 @@ test_xmlRegExecPushString2(void) {
value2 = gen_const_xmlChar_ptr(n_value2, 2);
data = gen_userdata(n_data, 3);
- ret_val = xmlRegExecPushString2(exec, (const xmlChar *)value, (const xmlChar *)value2, data);
+ ret_val = xmlRegExecPushString2(exec, value, value2, data);
desret_int(ret_val);
call_tests++;
des_xmlRegExecCtxtPtr(n_exec, exec, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
- des_const_xmlChar_ptr(n_value2, (const xmlChar *)value2, 2);
+ des_const_xmlChar_ptr(n_value, value, 1);
+ des_const_xmlChar_ptr(n_value2, value2, 2);
des_userdata(n_data, data, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -33489,7 +34428,7 @@ test_xmlRegexpExec(void) {
int ret_val;
xmlRegexpPtr comp; /* the compiled regular expression */
int n_comp;
- xmlChar * content; /* the value to check against the regular expression */
+ const xmlChar * content; /* the value to check against the regular expression */
int n_content;
for (n_comp = 0;n_comp < gen_nb_xmlRegexpPtr;n_comp++) {
@@ -33498,11 +34437,11 @@ test_xmlRegexpExec(void) {
comp = gen_xmlRegexpPtr(n_comp, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- ret_val = xmlRegexpExec(comp, (const xmlChar *)content);
+ ret_val = xmlRegexpExec(comp, content);
desret_int(ret_val);
call_tests++;
des_xmlRegexpPtr(n_comp, comp, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlRegexpExec",
@@ -33712,6 +34651,40 @@ test_xmlSaveDoc(void) {
}
+static int
+test_xmlSaveFinish(void) {
+ int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+ int mem_base;
+ int ret_val;
+ xmlSaveCtxtPtr ctxt; /* a document saving context */
+ int n_ctxt;
+
+ for (n_ctxt = 0;n_ctxt < gen_nb_xmlSaveCtxtPtr;n_ctxt++) {
+ mem_base = xmlMemBlocks();
+ ctxt = gen_xmlSaveCtxtPtr(n_ctxt, 0);
+
+ ret_val = xmlSaveFinish(ctxt);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlSaveCtxtPtr(n_ctxt, ctxt, 0);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlSaveFinish",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_ctxt);
+ printf("\n");
+ }
+ }
+ function_tests++;
+#endif
+
+ return(test_ret);
+}
+
+
static int
test_xmlSaveFlush(void) {
int test_ret = 0;
@@ -33912,17 +34885,17 @@ test_xmlThrDefTreeIndentString(void) {
#if defined(LIBXML_OUTPUT_ENABLED)
int mem_base;
const char * ret_val;
- char * v; /* */
+ const char * v; /* */
int n_v;
for (n_v = 0;n_v < gen_nb_const_char_ptr;n_v++) {
mem_base = xmlMemBlocks();
v = gen_const_char_ptr(n_v, 0);
- ret_val = xmlThrDefTreeIndentString((const char *)v);
+ ret_val = xmlThrDefTreeIndentString(v);
desret_const_char_ptr(ret_val);
call_tests++;
- des_const_char_ptr(n_v, (const char *)v, 0);
+ des_const_char_ptr(n_v, v, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlThrDefTreeIndentString",
@@ -33942,9 +34915,10 @@ static int
test_xmlsave(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing xmlsave : 7 of 13 functions ...\n");
+ if (quiet == 0) printf("Testing xmlsave : 8 of 14 functions ...\n");
test_ret += test_xmlSaveClose();
test_ret += test_xmlSaveDoc();
+ test_ret += test_xmlSaveFinish();
test_ret += test_xmlSaveFlush();
test_ret += test_xmlSaveSetAttrEscape();
test_ret += test_xmlSaveSetEscape();
@@ -34206,7 +35180,7 @@ test_xmlSchemaNewMemParserCtxt(void) {
#if defined(LIBXML_SCHEMAS_ENABLED)
int mem_base;
xmlSchemaParserCtxtPtr ret_val;
- char * buffer; /* a pointer to a char array containing the schemas */
+ const char * buffer; /* a pointer to a char array containing the schemas */
int n_buffer;
int size; /* the size of the array */
int n_size;
@@ -34220,10 +35194,10 @@ test_xmlSchemaNewMemParserCtxt(void) {
(size > xmlStrlen(BAD_CAST buffer)))
size = 0;
- ret_val = xmlSchemaNewMemParserCtxt((const char *)buffer, size);
+ ret_val = xmlSchemaNewMemParserCtxt(buffer, size);
desret_xmlSchemaParserCtxtPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+ des_const_char_ptr(n_buffer, buffer, 0);
des_int(n_size, size, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -34250,17 +35224,17 @@ test_xmlSchemaNewParserCtxt(void) {
#if defined(LIBXML_SCHEMAS_ENABLED)
int mem_base;
xmlSchemaParserCtxtPtr ret_val;
- char * URL; /* the location of the schema */
+ const char * URL; /* the location of the schema */
int n_URL;
for (n_URL = 0;n_URL < gen_nb_const_char_ptr;n_URL++) {
mem_base = xmlMemBlocks();
URL = gen_const_char_ptr(n_URL, 0);
- ret_val = xmlSchemaNewParserCtxt((const char *)URL);
+ ret_val = xmlSchemaNewParserCtxt(URL);
desret_xmlSchemaParserCtxtPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_URL, (const char *)URL, 0);
+ des_const_char_ptr(n_URL, URL, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSchemaNewParserCtxt",
@@ -34799,7 +35773,7 @@ test_xmlSchemaCheckFacet(void) {
int n_typeDecl;
xmlSchemaParserCtxtPtr pctxt; /* the schema parser context or NULL */
int n_pctxt;
- xmlChar * name; /* the optional name of the type */
+ const xmlChar * name; /* the optional name of the type */
int n_name;
for (n_facet = 0;n_facet < gen_nb_xmlSchemaFacetPtr;n_facet++) {
@@ -34812,13 +35786,13 @@ test_xmlSchemaCheckFacet(void) {
pctxt = gen_xmlSchemaParserCtxtPtr(n_pctxt, 2);
name = gen_const_xmlChar_ptr(n_name, 3);
- ret_val = xmlSchemaCheckFacet(facet, typeDecl, pctxt, (const xmlChar *)name);
+ ret_val = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
desret_int(ret_val);
call_tests++;
des_xmlSchemaFacetPtr(n_facet, facet, 0);
des_xmlSchemaTypePtr(n_typeDecl, typeDecl, 1);
des_xmlSchemaParserCtxtPtr(n_pctxt, pctxt, 2);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 3);
+ des_const_xmlChar_ptr(n_name, name, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSchemaCheckFacet",
@@ -34865,17 +35839,17 @@ test_xmlSchemaCollapseString(void) {
#if defined(LIBXML_SCHEMAS_ENABLED)
int mem_base;
xmlChar * ret_val;
- xmlChar * value; /* a value */
+ const xmlChar * value; /* a value */
int n_value;
for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
mem_base = xmlMemBlocks();
value = gen_const_xmlChar_ptr(n_value, 0);
- ret_val = xmlSchemaCollapseString((const xmlChar *)value);
+ ret_val = xmlSchemaCollapseString(value);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSchemaCollapseString",
@@ -35073,7 +36047,7 @@ test_xmlSchemaGetCanonValue(void) {
int ret_val;
xmlSchemaValPtr val; /* the precomputed value */
int n_val;
- xmlChar ** retValue; /* the returned value */
+ const xmlChar ** retValue; /* the returned value */
int n_retValue;
for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
@@ -35082,11 +36056,11 @@ test_xmlSchemaGetCanonValue(void) {
val = gen_xmlSchemaValPtr(n_val, 0);
retValue = gen_const_xmlChar_ptr_ptr(n_retValue, 1);
- ret_val = xmlSchemaGetCanonValue(val, (const xmlChar **)retValue);
+ ret_val = xmlSchemaGetCanonValue(val, retValue);
desret_int(ret_val);
call_tests++;
des_xmlSchemaValPtr(n_val, val, 0);
- des_const_xmlChar_ptr_ptr(n_retValue, (const xmlChar **)retValue, 1);
+ des_const_xmlChar_ptr_ptr(n_retValue, retValue, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSchemaGetCanonValue",
@@ -35114,7 +36088,7 @@ test_xmlSchemaGetCanonValueWhtsp(void) {
int ret_val;
xmlSchemaValPtr val; /* the precomputed value */
int n_val;
- xmlChar ** retValue; /* the returned value */
+ const xmlChar ** retValue; /* the returned value */
int n_retValue;
xmlSchemaWhitespaceValueType ws; /* the whitespace type of the value */
int n_ws;
@@ -35127,11 +36101,11 @@ test_xmlSchemaGetCanonValueWhtsp(void) {
retValue = gen_const_xmlChar_ptr_ptr(n_retValue, 1);
ws = gen_xmlSchemaWhitespaceValueType(n_ws, 2);
- ret_val = xmlSchemaGetCanonValueWhtsp(val, (const xmlChar **)retValue, ws);
+ ret_val = xmlSchemaGetCanonValueWhtsp(val, retValue, ws);
desret_int(ret_val);
call_tests++;
des_xmlSchemaValPtr(n_val, val, 0);
- des_const_xmlChar_ptr_ptr(n_retValue, (const xmlChar **)retValue, 1);
+ des_const_xmlChar_ptr_ptr(n_retValue, retValue, 1);
des_xmlSchemaWhitespaceValueType(n_ws, ws, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -35194,9 +36168,9 @@ test_xmlSchemaGetPredefinedType(void) {
#if defined(LIBXML_SCHEMAS_ENABLED)
int mem_base;
xmlSchemaTypePtr ret_val;
- xmlChar * name; /* the type name */
+ const xmlChar * name; /* the type name */
int n_name;
- xmlChar * ns; /* the URI of the namespace usually "http://www.w3.org/2001/XMLSchema" */
+ const xmlChar * ns; /* the URI of the namespace usually "http://www.w3.org/2001/XMLSchema" */
int n_ns;
for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
@@ -35205,11 +36179,11 @@ test_xmlSchemaGetPredefinedType(void) {
name = gen_const_xmlChar_ptr(n_name, 0);
ns = gen_const_xmlChar_ptr(n_ns, 1);
- ret_val = xmlSchemaGetPredefinedType((const xmlChar *)name, (const xmlChar *)ns);
+ ret_val = xmlSchemaGetPredefinedType(name, ns);
desret_xmlSchemaTypePtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
- des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 1);
+ des_const_xmlChar_ptr(n_name, name, 0);
+ des_const_xmlChar_ptr(n_ns, ns, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSchemaGetPredefinedType",
@@ -35378,7 +36352,7 @@ test_xmlSchemaValPredefTypeNode(void) {
int ret_val;
xmlSchemaTypePtr type; /* the predefined type */
int n_type;
- xmlChar * value; /* the value to check */
+ const xmlChar * value; /* the value to check */
int n_value;
xmlSchemaValPtr * val; /* the return computed value */
int n_val;
@@ -35395,11 +36369,11 @@ test_xmlSchemaValPredefTypeNode(void) {
val = gen_xmlSchemaValPtr_ptr(n_val, 2);
node = gen_xmlNodePtr(n_node, 3);
- ret_val = xmlSchemaValPredefTypeNode(type, (const xmlChar *)value, val, node);
+ ret_val = xmlSchemaValPredefTypeNode(type, value, val, node);
desret_int(ret_val);
call_tests++;
des_xmlSchemaTypePtr(n_type, type, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
des_xmlSchemaValPtr_ptr(n_val, val, 2);
des_xmlNodePtr(n_node, node, 3);
xmlResetLastError();
@@ -35433,7 +36407,7 @@ test_xmlSchemaValPredefTypeNodeNoNorm(void) {
int ret_val;
xmlSchemaTypePtr type; /* the predefined type */
int n_type;
- xmlChar * value; /* the value to check */
+ const xmlChar * value; /* the value to check */
int n_value;
xmlSchemaValPtr * val; /* the return computed value */
int n_val;
@@ -35450,11 +36424,11 @@ test_xmlSchemaValPredefTypeNodeNoNorm(void) {
val = gen_xmlSchemaValPtr_ptr(n_val, 2);
node = gen_xmlNodePtr(n_node, 3);
- ret_val = xmlSchemaValPredefTypeNodeNoNorm(type, (const xmlChar *)value, val, node);
+ ret_val = xmlSchemaValPredefTypeNodeNoNorm(type, value, val, node);
desret_int(ret_val);
call_tests++;
des_xmlSchemaTypePtr(n_type, type, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
des_xmlSchemaValPtr_ptr(n_val, val, 2);
des_xmlNodePtr(n_node, node, 3);
xmlResetLastError();
@@ -35490,7 +36464,7 @@ test_xmlSchemaValidateFacet(void) {
int n_base;
xmlSchemaFacetPtr facet; /* the facet to check */
int n_facet;
- xmlChar * value; /* the lexical repr of the value to validate */
+ const xmlChar * value; /* the lexical repr of the value to validate */
int n_value;
xmlSchemaValPtr val; /* the precomputed value */
int n_val;
@@ -35505,12 +36479,12 @@ test_xmlSchemaValidateFacet(void) {
value = gen_const_xmlChar_ptr(n_value, 2);
val = gen_xmlSchemaValPtr(n_val, 3);
- ret_val = xmlSchemaValidateFacet(base, facet, (const xmlChar *)value, val);
+ ret_val = xmlSchemaValidateFacet(base, facet, value, val);
desret_int(ret_val);
call_tests++;
des_xmlSchemaTypePtr(n_base, base, 0);
des_xmlSchemaFacetPtr(n_facet, facet, 1);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+ des_const_xmlChar_ptr(n_value, value, 2);
des_xmlSchemaValPtr(n_val, val, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -35547,7 +36521,7 @@ test_xmlSchemaValidateFacetWhtsp(void) {
int n_fws;
xmlSchemaValType valType; /* the built-in type of the value */
int n_valType;
- xmlChar * value; /* the lexical (or normalized for pattern) repr of the value to validate */
+ const xmlChar * value; /* the lexical (or normalized for pattern) repr of the value to validate */
int n_value;
xmlSchemaValPtr val; /* the precomputed value */
int n_val;
@@ -35568,13 +36542,13 @@ test_xmlSchemaValidateFacetWhtsp(void) {
val = gen_xmlSchemaValPtr(n_val, 4);
ws = gen_xmlSchemaWhitespaceValueType(n_ws, 5);
- ret_val = xmlSchemaValidateFacetWhtsp(facet, fws, valType, (const xmlChar *)value, val, ws);
+ ret_val = xmlSchemaValidateFacetWhtsp(facet, fws, valType, value, val, ws);
desret_int(ret_val);
call_tests++;
des_xmlSchemaFacetPtr(n_facet, facet, 0);
des_xmlSchemaWhitespaceValueType(n_fws, fws, 1);
des_xmlSchemaValType(n_valType, valType, 2);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+ des_const_xmlChar_ptr(n_value, value, 3);
des_xmlSchemaValPtr(n_val, val, 4);
des_xmlSchemaWhitespaceValueType(n_ws, ws, 5);
xmlResetLastError();
@@ -35614,7 +36588,7 @@ test_xmlSchemaValidateLengthFacet(void) {
int n_type;
xmlSchemaFacetPtr facet; /* the facet to check */
int n_facet;
- xmlChar * value; /* the lexical repr. of the value to be validated */
+ const xmlChar * value; /* the lexical repr. of the value to be validated */
int n_value;
xmlSchemaValPtr val; /* the precomputed value */
int n_val;
@@ -35633,12 +36607,12 @@ test_xmlSchemaValidateLengthFacet(void) {
val = gen_xmlSchemaValPtr(n_val, 3);
length = gen_unsigned_long_ptr(n_length, 4);
- ret_val = xmlSchemaValidateLengthFacet(type, facet, (const xmlChar *)value, val, length);
+ ret_val = xmlSchemaValidateLengthFacet(type, facet, value, val, length);
desret_int(ret_val);
call_tests++;
des_xmlSchemaTypePtr(n_type, type, 0);
des_xmlSchemaFacetPtr(n_facet, facet, 1);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+ des_const_xmlChar_ptr(n_value, value, 2);
des_xmlSchemaValPtr(n_val, val, 3);
des_unsigned_long_ptr(n_length, length, 4);
xmlResetLastError();
@@ -35676,7 +36650,7 @@ test_xmlSchemaValidateLengthFacetWhtsp(void) {
int n_facet;
xmlSchemaValType valType; /* the built-in type */
int n_valType;
- xmlChar * value; /* the lexical repr. of the value to be validated */
+ const xmlChar * value; /* the lexical repr. of the value to be validated */
int n_value;
xmlSchemaValPtr val; /* the precomputed value */
int n_val;
@@ -35699,12 +36673,12 @@ test_xmlSchemaValidateLengthFacetWhtsp(void) {
length = gen_unsigned_long_ptr(n_length, 4);
ws = gen_xmlSchemaWhitespaceValueType(n_ws, 5);
- ret_val = xmlSchemaValidateLengthFacetWhtsp(facet, valType, (const xmlChar *)value, val, length, ws);
+ ret_val = xmlSchemaValidateLengthFacetWhtsp(facet, valType, value, val, length, ws);
desret_int(ret_val);
call_tests++;
des_xmlSchemaFacetPtr(n_facet, facet, 0);
des_xmlSchemaValType(n_valType, valType, 1);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+ des_const_xmlChar_ptr(n_value, value, 2);
des_xmlSchemaValPtr(n_val, val, 3);
des_unsigned_long_ptr(n_length, length, 4);
des_xmlSchemaWhitespaceValueType(n_ws, ws, 5);
@@ -35743,7 +36717,7 @@ test_xmlSchemaValidateListSimpleTypeFacet(void) {
int ret_val;
xmlSchemaFacetPtr facet; /* the facet to check */
int n_facet;
- xmlChar * value; /* the lexical repr of the value to validate */
+ const xmlChar * value; /* the lexical repr of the value to validate */
int n_value;
unsigned long actualLen; /* the number of list items */
int n_actualLen;
@@ -35760,11 +36734,11 @@ test_xmlSchemaValidateListSimpleTypeFacet(void) {
actualLen = gen_unsigned_long(n_actualLen, 2);
expectedLen = gen_unsigned_long_ptr(n_expectedLen, 3);
- ret_val = xmlSchemaValidateListSimpleTypeFacet(facet, (const xmlChar *)value, actualLen, expectedLen);
+ ret_val = xmlSchemaValidateListSimpleTypeFacet(facet, value, actualLen, expectedLen);
desret_int(ret_val);
call_tests++;
des_xmlSchemaFacetPtr(n_facet, facet, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
des_unsigned_long(n_actualLen, actualLen, 2);
des_unsigned_long_ptr(n_expectedLen, expectedLen, 3);
xmlResetLastError();
@@ -35798,7 +36772,7 @@ test_xmlSchemaValidatePredefinedType(void) {
int ret_val;
xmlSchemaTypePtr type; /* the predefined type */
int n_type;
- xmlChar * value; /* the value to check */
+ const xmlChar * value; /* the value to check */
int n_value;
xmlSchemaValPtr * val; /* the return computed value */
int n_val;
@@ -35811,11 +36785,11 @@ test_xmlSchemaValidatePredefinedType(void) {
value = gen_const_xmlChar_ptr(n_value, 1);
val = gen_xmlSchemaValPtr_ptr(n_val, 2);
- ret_val = xmlSchemaValidatePredefinedType(type, (const xmlChar *)value, val);
+ ret_val = xmlSchemaValidatePredefinedType(type, value, val);
desret_int(ret_val);
call_tests++;
des_xmlSchemaTypePtr(n_type, type, 0);
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+ des_const_xmlChar_ptr(n_value, value, 1);
des_xmlSchemaValPtr_ptr(n_val, val, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -35963,17 +36937,17 @@ test_xmlSchemaWhiteSpaceReplace(void) {
#if defined(LIBXML_SCHEMAS_ENABLED)
int mem_base;
xmlChar * ret_val;
- xmlChar * value; /* a value */
+ const xmlChar * value; /* a value */
int n_value;
for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
mem_base = xmlMemBlocks();
value = gen_const_xmlChar_ptr(n_value, 0);
- ret_val = xmlSchemaWhiteSpaceReplace((const xmlChar *)value);
+ ret_val = xmlSchemaWhiteSpaceReplace(value);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+ des_const_xmlChar_ptr(n_value, value, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlSchemaWhiteSpaceReplace",
@@ -36038,17 +37012,17 @@ test_xmlCharStrdup(void) {
int mem_base;
xmlChar * ret_val;
- char * cur; /* the input char * */
+ const char * cur; /* the input char * */
int n_cur;
for (n_cur = 0;n_cur < gen_nb_const_char_ptr;n_cur++) {
mem_base = xmlMemBlocks();
cur = gen_const_char_ptr(n_cur, 0);
- ret_val = xmlCharStrdup((const char *)cur);
+ ret_val = xmlCharStrdup(cur);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_char_ptr(n_cur, (const char *)cur, 0);
+ des_const_char_ptr(n_cur, cur, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCharStrdup",
@@ -36070,7 +37044,7 @@ test_xmlCharStrndup(void) {
int mem_base;
xmlChar * ret_val;
- char * cur; /* the input char * */
+ const char * cur; /* the input char * */
int n_cur;
int len; /* the len of @cur */
int n_len;
@@ -36084,10 +37058,10 @@ test_xmlCharStrndup(void) {
(len > xmlStrlen(BAD_CAST cur)))
len = 0;
- ret_val = xmlCharStrndup((const char *)cur, len);
+ ret_val = xmlCharStrndup(cur, len);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_char_ptr(n_cur, (const char *)cur, 0);
+ des_const_char_ptr(n_cur, cur, 0);
des_int(n_len, len, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -36112,17 +37086,17 @@ test_xmlCheckUTF8(void) {
int mem_base;
int ret_val;
- unsigned char * utf; /* Pointer to putative UTF-8 encoded string. */
+ const unsigned char * utf; /* Pointer to putative UTF-8 encoded string. */
int n_utf;
for (n_utf = 0;n_utf < gen_nb_const_unsigned_char_ptr;n_utf++) {
mem_base = xmlMemBlocks();
utf = gen_const_unsigned_char_ptr(n_utf, 0);
- ret_val = xmlCheckUTF8((const unsigned char *)utf);
+ ret_val = xmlCheckUTF8(utf);
desret_int(ret_val);
call_tests++;
- des_const_unsigned_char_ptr(n_utf, (const unsigned char *)utf, 0);
+ des_const_unsigned_char_ptr(n_utf, utf, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlCheckUTF8",
@@ -36144,7 +37118,7 @@ test_xmlGetUTF8Char(void) {
int mem_base;
int ret_val;
- unsigned char * utf; /* a sequence of UTF-8 encoded bytes */
+ const unsigned char * utf; /* a sequence of UTF-8 encoded bytes */
int n_utf;
int * len; /* a pointer to the minimum number of bytes present in the sequence. This is used to assure the next character is completely contained within the sequence. */
int n_len;
@@ -36155,10 +37129,10 @@ test_xmlGetUTF8Char(void) {
utf = gen_const_unsigned_char_ptr(n_utf, 0);
len = gen_int_ptr(n_len, 1);
- ret_val = xmlGetUTF8Char((const unsigned char *)utf, len);
+ ret_val = xmlGetUTF8Char(utf, len);
desret_int(ret_val);
call_tests++;
- des_const_unsigned_char_ptr(n_utf, (const unsigned char *)utf, 0);
+ des_const_unsigned_char_ptr(n_utf, utf, 0);
des_int_ptr(n_len, len, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -36183,9 +37157,9 @@ test_xmlStrEqual(void) {
int mem_base;
int ret_val;
- xmlChar * str1; /* the first xmlChar * */
+ const xmlChar * str1; /* the first xmlChar * */
int n_str1;
- xmlChar * str2; /* the second xmlChar * */
+ const xmlChar * str2; /* the second xmlChar * */
int n_str2;
for (n_str1 = 0;n_str1 < gen_nb_const_xmlChar_ptr;n_str1++) {
@@ -36194,11 +37168,11 @@ test_xmlStrEqual(void) {
str1 = gen_const_xmlChar_ptr(n_str1, 0);
str2 = gen_const_xmlChar_ptr(n_str2, 1);
- ret_val = xmlStrEqual((const xmlChar *)str1, (const xmlChar *)str2);
+ ret_val = xmlStrEqual(str1, str2);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
- des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+ des_const_xmlChar_ptr(n_str1, str1, 0);
+ des_const_xmlChar_ptr(n_str2, str2, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStrEqual",
@@ -36232,11 +37206,11 @@ test_xmlStrQEqual(void) {
int mem_base;
int ret_val;
- xmlChar * pref; /* the prefix of the QName */
+ const xmlChar * pref; /* the prefix of the QName */
int n_pref;
- xmlChar * name; /* the localname of the QName */
+ const xmlChar * name; /* the localname of the QName */
int n_name;
- xmlChar * str; /* the second xmlChar * */
+ const xmlChar * str; /* the second xmlChar * */
int n_str;
for (n_pref = 0;n_pref < gen_nb_const_xmlChar_ptr;n_pref++) {
@@ -36247,12 +37221,12 @@ test_xmlStrQEqual(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
str = gen_const_xmlChar_ptr(n_str, 2);
- ret_val = xmlStrQEqual((const xmlChar *)pref, (const xmlChar *)name, (const xmlChar *)str);
+ ret_val = xmlStrQEqual(pref, name, str);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_pref, (const xmlChar *)pref, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 2);
+ des_const_xmlChar_ptr(n_pref, pref, 0);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_str, str, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStrQEqual",
@@ -36288,9 +37262,9 @@ test_xmlStrcasecmp(void) {
int mem_base;
int ret_val;
- xmlChar * str1; /* the first xmlChar * */
+ const xmlChar * str1; /* the first xmlChar * */
int n_str1;
- xmlChar * str2; /* the second xmlChar * */
+ const xmlChar * str2; /* the second xmlChar * */
int n_str2;
for (n_str1 = 0;n_str1 < gen_nb_const_xmlChar_ptr;n_str1++) {
@@ -36299,11 +37273,11 @@ test_xmlStrcasecmp(void) {
str1 = gen_const_xmlChar_ptr(n_str1, 0);
str2 = gen_const_xmlChar_ptr(n_str2, 1);
- ret_val = xmlStrcasecmp((const xmlChar *)str1, (const xmlChar *)str2);
+ ret_val = xmlStrcasecmp(str1, str2);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
- des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+ des_const_xmlChar_ptr(n_str1, str1, 0);
+ des_const_xmlChar_ptr(n_str2, str2, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStrcasecmp",
@@ -36327,9 +37301,9 @@ test_xmlStrcasestr(void) {
int mem_base;
const xmlChar * ret_val;
- xmlChar * str; /* the xmlChar * array (haystack) */
+ const xmlChar * str; /* the xmlChar * array (haystack) */
int n_str;
- xmlChar * val; /* the xmlChar to search (needle) */
+ const xmlChar * val; /* the xmlChar to search (needle) */
int n_val;
for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
@@ -36338,11 +37312,11 @@ test_xmlStrcasestr(void) {
str = gen_const_xmlChar_ptr(n_str, 0);
val = gen_const_xmlChar_ptr(n_val, 1);
- ret_val = xmlStrcasestr((const xmlChar *)str, (const xmlChar *)val);
+ ret_val = xmlStrcasestr(str, val);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
- des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 1);
+ des_const_xmlChar_ptr(n_str, str, 0);
+ des_const_xmlChar_ptr(n_val, val, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStrcasestr",
@@ -36366,7 +37340,7 @@ test_xmlStrchr(void) {
int mem_base;
const xmlChar * ret_val;
- xmlChar * str; /* the xmlChar * array */
+ const xmlChar * str; /* the xmlChar * array */
int n_str;
xmlChar val; /* the xmlChar to search */
int n_val;
@@ -36377,10 +37351,10 @@ test_xmlStrchr(void) {
str = gen_const_xmlChar_ptr(n_str, 0);
val = gen_xmlChar(n_val, 1);
- ret_val = xmlStrchr((const xmlChar *)str, val);
+ ret_val = xmlStrchr(str, val);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+ des_const_xmlChar_ptr(n_str, str, 0);
des_xmlChar(n_val, val, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -36405,9 +37379,9 @@ test_xmlStrcmp(void) {
int mem_base;
int ret_val;
- xmlChar * str1; /* the first xmlChar * */
+ const xmlChar * str1; /* the first xmlChar * */
int n_str1;
- xmlChar * str2; /* the second xmlChar * */
+ const xmlChar * str2; /* the second xmlChar * */
int n_str2;
for (n_str1 = 0;n_str1 < gen_nb_const_xmlChar_ptr;n_str1++) {
@@ -36416,11 +37390,11 @@ test_xmlStrcmp(void) {
str1 = gen_const_xmlChar_ptr(n_str1, 0);
str2 = gen_const_xmlChar_ptr(n_str2, 1);
- ret_val = xmlStrcmp((const xmlChar *)str1, (const xmlChar *)str2);
+ ret_val = xmlStrcmp(str1, str2);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
- des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+ des_const_xmlChar_ptr(n_str1, str1, 0);
+ des_const_xmlChar_ptr(n_str2, str2, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStrcmp",
@@ -36444,17 +37418,17 @@ test_xmlStrdup(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * cur; /* the input xmlChar * */
+ const xmlChar * cur; /* the input xmlChar * */
int n_cur;
for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
mem_base = xmlMemBlocks();
cur = gen_const_xmlChar_ptr(n_cur, 0);
- ret_val = xmlStrdup((const xmlChar *)cur);
+ ret_val = xmlStrdup(cur);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+ des_const_xmlChar_ptr(n_cur, cur, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStrdup",
@@ -36476,17 +37450,17 @@ test_xmlStrlen(void) {
int mem_base;
int ret_val;
- xmlChar * str; /* the xmlChar * array */
+ const xmlChar * str; /* the xmlChar * array */
int n_str;
for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
mem_base = xmlMemBlocks();
str = gen_const_xmlChar_ptr(n_str, 0);
- ret_val = xmlStrlen((const xmlChar *)str);
+ ret_val = xmlStrlen(str);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+ des_const_xmlChar_ptr(n_str, str, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStrlen",
@@ -36508,9 +37482,9 @@ test_xmlStrncasecmp(void) {
int mem_base;
int ret_val;
- xmlChar * str1; /* the first xmlChar * */
+ const xmlChar * str1; /* the first xmlChar * */
int n_str1;
- xmlChar * str2; /* the second xmlChar * */
+ const xmlChar * str2; /* the second xmlChar * */
int n_str2;
int len; /* the max comparison length */
int n_len;
@@ -36526,11 +37500,11 @@ test_xmlStrncasecmp(void) {
(len > xmlStrlen(BAD_CAST str2)))
len = 0;
- ret_val = xmlStrncasecmp((const xmlChar *)str1, (const xmlChar *)str2, len);
+ ret_val = xmlStrncasecmp(str1, str2, len);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
- des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+ des_const_xmlChar_ptr(n_str1, str1, 0);
+ des_const_xmlChar_ptr(n_str2, str2, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -36557,9 +37531,9 @@ test_xmlStrncatNew(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * str1; /* first xmlChar string */
+ const xmlChar * str1; /* first xmlChar string */
int n_str1;
- xmlChar * str2; /* second xmlChar string */
+ const xmlChar * str2; /* second xmlChar string */
int n_str2;
int len; /* the len of @str2 or < 0 */
int n_len;
@@ -36575,11 +37549,11 @@ test_xmlStrncatNew(void) {
(len > xmlStrlen(BAD_CAST str2)))
len = 0;
- ret_val = xmlStrncatNew((const xmlChar *)str1, (const xmlChar *)str2, len);
+ ret_val = xmlStrncatNew(str1, str2, len);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
- des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+ des_const_xmlChar_ptr(n_str1, str1, 0);
+ des_const_xmlChar_ptr(n_str2, str2, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -36606,9 +37580,9 @@ test_xmlStrncmp(void) {
int mem_base;
int ret_val;
- xmlChar * str1; /* the first xmlChar * */
+ const xmlChar * str1; /* the first xmlChar * */
int n_str1;
- xmlChar * str2; /* the second xmlChar * */
+ const xmlChar * str2; /* the second xmlChar * */
int n_str2;
int len; /* the max comparison length */
int n_len;
@@ -36624,11 +37598,11 @@ test_xmlStrncmp(void) {
(len > xmlStrlen(BAD_CAST str2)))
len = 0;
- ret_val = xmlStrncmp((const xmlChar *)str1, (const xmlChar *)str2, len);
+ ret_val = xmlStrncmp(str1, str2, len);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
- des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+ des_const_xmlChar_ptr(n_str1, str1, 0);
+ des_const_xmlChar_ptr(n_str2, str2, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -36655,7 +37629,7 @@ test_xmlStrndup(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * cur; /* the input xmlChar * */
+ const xmlChar * cur; /* the input xmlChar * */
int n_cur;
int len; /* the len of @cur */
int n_len;
@@ -36669,10 +37643,10 @@ test_xmlStrndup(void) {
(len > xmlStrlen(BAD_CAST cur)))
len = 0;
- ret_val = xmlStrndup((const xmlChar *)cur, len);
+ ret_val = xmlStrndup(cur, len);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+ des_const_xmlChar_ptr(n_cur, cur, 0);
des_int(n_len, len, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -36697,9 +37671,9 @@ test_xmlStrstr(void) {
int mem_base;
const xmlChar * ret_val;
- xmlChar * str; /* the xmlChar * array (haystack) */
+ const xmlChar * str; /* the xmlChar * array (haystack) */
int n_str;
- xmlChar * val; /* the xmlChar to search (needle) */
+ const xmlChar * val; /* the xmlChar to search (needle) */
int n_val;
for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
@@ -36708,11 +37682,11 @@ test_xmlStrstr(void) {
str = gen_const_xmlChar_ptr(n_str, 0);
val = gen_const_xmlChar_ptr(n_val, 1);
- ret_val = xmlStrstr((const xmlChar *)str, (const xmlChar *)val);
+ ret_val = xmlStrstr(str, val);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
- des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 1);
+ des_const_xmlChar_ptr(n_str, str, 0);
+ des_const_xmlChar_ptr(n_val, val, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlStrstr",
@@ -36736,7 +37710,7 @@ test_xmlStrsub(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * str; /* the xmlChar * array (haystack) */
+ const xmlChar * str; /* the xmlChar * array (haystack) */
int n_str;
int start; /* the index of the first char (zero based) */
int n_start;
@@ -36757,10 +37731,10 @@ test_xmlStrsub(void) {
(len > xmlStrlen(BAD_CAST str)))
len = 0;
- ret_val = xmlStrsub((const xmlChar *)str, start, len);
+ ret_val = xmlStrsub(str, start, len);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+ des_const_xmlChar_ptr(n_str, str, 0);
des_int(n_start, start, 1);
des_int(n_len, len, 2);
xmlResetLastError();
@@ -36788,9 +37762,9 @@ test_xmlUTF8Charcmp(void) {
int mem_base;
int ret_val;
- xmlChar * utf1; /* pointer to first UTF8 char */
+ const xmlChar * utf1; /* pointer to first UTF8 char */
int n_utf1;
- xmlChar * utf2; /* pointer to second UTF8 char */
+ const xmlChar * utf2; /* pointer to second UTF8 char */
int n_utf2;
for (n_utf1 = 0;n_utf1 < gen_nb_const_xmlChar_ptr;n_utf1++) {
@@ -36799,11 +37773,11 @@ test_xmlUTF8Charcmp(void) {
utf1 = gen_const_xmlChar_ptr(n_utf1, 0);
utf2 = gen_const_xmlChar_ptr(n_utf2, 1);
- ret_val = xmlUTF8Charcmp((const xmlChar *)utf1, (const xmlChar *)utf2);
+ ret_val = xmlUTF8Charcmp(utf1, utf2);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_utf1, (const xmlChar *)utf1, 0);
- des_const_xmlChar_ptr(n_utf2, (const xmlChar *)utf2, 1);
+ des_const_xmlChar_ptr(n_utf1, utf1, 0);
+ des_const_xmlChar_ptr(n_utf2, utf2, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlUTF8Charcmp",
@@ -36827,17 +37801,17 @@ test_xmlUTF8Size(void) {
int mem_base;
int ret_val;
- xmlChar * utf; /* pointer to the UTF8 character */
+ const xmlChar * utf; /* pointer to the UTF8 character */
int n_utf;
for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
mem_base = xmlMemBlocks();
utf = gen_const_xmlChar_ptr(n_utf, 0);
- ret_val = xmlUTF8Size((const xmlChar *)utf);
+ ret_val = xmlUTF8Size(utf);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+ des_const_xmlChar_ptr(n_utf, utf, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlUTF8Size",
@@ -36859,17 +37833,17 @@ test_xmlUTF8Strlen(void) {
int mem_base;
int ret_val;
- xmlChar * utf; /* a sequence of UTF-8 encoded bytes */
+ const xmlChar * utf; /* a sequence of UTF-8 encoded bytes */
int n_utf;
for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
mem_base = xmlMemBlocks();
utf = gen_const_xmlChar_ptr(n_utf, 0);
- ret_val = xmlUTF8Strlen((const xmlChar *)utf);
+ ret_val = xmlUTF8Strlen(utf);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+ des_const_xmlChar_ptr(n_utf, utf, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlUTF8Strlen",
@@ -36891,9 +37865,9 @@ test_xmlUTF8Strloc(void) {
int mem_base;
int ret_val;
- xmlChar * utf; /* the input UTF8 * */
+ const xmlChar * utf; /* the input UTF8 * */
int n_utf;
- xmlChar * utfchar; /* the UTF8 character to be found */
+ const xmlChar * utfchar; /* the UTF8 character to be found */
int n_utfchar;
for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
@@ -36902,11 +37876,11 @@ test_xmlUTF8Strloc(void) {
utf = gen_const_xmlChar_ptr(n_utf, 0);
utfchar = gen_const_xmlChar_ptr(n_utfchar, 1);
- ret_val = xmlUTF8Strloc((const xmlChar *)utf, (const xmlChar *)utfchar);
+ ret_val = xmlUTF8Strloc(utf, utfchar);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
- des_const_xmlChar_ptr(n_utfchar, (const xmlChar *)utfchar, 1);
+ des_const_xmlChar_ptr(n_utf, utf, 0);
+ des_const_xmlChar_ptr(n_utfchar, utfchar, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlUTF8Strloc",
@@ -36930,7 +37904,7 @@ test_xmlUTF8Strndup(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * utf; /* the input UTF8 * */
+ const xmlChar * utf; /* the input UTF8 * */
int n_utf;
int len; /* the len of @utf (in chars) */
int n_len;
@@ -36944,10 +37918,10 @@ test_xmlUTF8Strndup(void) {
(len > xmlStrlen(BAD_CAST utf)))
len = 0;
- ret_val = xmlUTF8Strndup((const xmlChar *)utf, len);
+ ret_val = xmlUTF8Strndup(utf, len);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+ des_const_xmlChar_ptr(n_utf, utf, 0);
des_int(n_len, len, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -36972,7 +37946,7 @@ test_xmlUTF8Strpos(void) {
int mem_base;
const xmlChar * ret_val;
- xmlChar * utf; /* the input UTF8 * */
+ const xmlChar * utf; /* the input UTF8 * */
int n_utf;
int pos; /* the position of the desired UTF8 char (in chars) */
int n_pos;
@@ -36983,10 +37957,10 @@ test_xmlUTF8Strpos(void) {
utf = gen_const_xmlChar_ptr(n_utf, 0);
pos = gen_int(n_pos, 1);
- ret_val = xmlUTF8Strpos((const xmlChar *)utf, pos);
+ ret_val = xmlUTF8Strpos(utf, pos);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+ des_const_xmlChar_ptr(n_utf, utf, 0);
des_int(n_pos, pos, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -37011,7 +37985,7 @@ test_xmlUTF8Strsize(void) {
int mem_base;
int ret_val;
- xmlChar * utf; /* a sequence of UTF-8 encoded bytes */
+ const xmlChar * utf; /* a sequence of UTF-8 encoded bytes */
int n_utf;
int len; /* the number of characters in the array */
int n_len;
@@ -37025,10 +37999,10 @@ test_xmlUTF8Strsize(void) {
(len > xmlStrlen(BAD_CAST utf)))
len = 0;
- ret_val = xmlUTF8Strsize((const xmlChar *)utf, len);
+ ret_val = xmlUTF8Strsize(utf, len);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+ des_const_xmlChar_ptr(n_utf, utf, 0);
des_int(n_len, len, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -37053,7 +38027,7 @@ test_xmlUTF8Strsub(void) {
int mem_base;
xmlChar * ret_val;
- xmlChar * utf; /* a sequence of UTF-8 encoded bytes */
+ const xmlChar * utf; /* a sequence of UTF-8 encoded bytes */
int n_utf;
int start; /* relative pos of first char */
int n_start;
@@ -37074,10 +38048,10 @@ test_xmlUTF8Strsub(void) {
(len > xmlStrlen(BAD_CAST utf)))
len = 0;
- ret_val = xmlUTF8Strsub((const xmlChar *)utf, start, len);
+ ret_val = xmlUTF8Strsub(utf, start, len);
desret_xmlChar_ptr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+ des_const_xmlChar_ptr(n_utf, utf, 0);
des_int(n_start, start, 1);
des_int(n_len, len, 2);
xmlResetLastError();
@@ -37452,7 +38426,7 @@ test_xmlUCSIsBlock(void) {
int ret_val;
int code; /* UCS code point */
int n_code;
- char * block; /* UCS block name */
+ const char * block; /* UCS block name */
int n_block;
for (n_code = 0;n_code < gen_nb_int;n_code++) {
@@ -37461,11 +38435,11 @@ test_xmlUCSIsBlock(void) {
code = gen_int(n_code, 0);
block = gen_const_char_ptr(n_block, 1);
- ret_val = xmlUCSIsBlock(code, (const char *)block);
+ ret_val = xmlUCSIsBlock(code, block);
desret_int(ret_val);
call_tests++;
des_int(n_code, code, 0);
- des_const_char_ptr(n_block, (const char *)block, 1);
+ des_const_char_ptr(n_block, block, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlUCSIsBlock",
@@ -38037,7 +39011,7 @@ test_xmlUCSIsCat(void) {
int ret_val;
int code; /* UCS code point */
int n_code;
- char * cat; /* UCS Category name */
+ const char * cat; /* UCS Category name */
int n_cat;
for (n_code = 0;n_code < gen_nb_int;n_code++) {
@@ -38046,11 +39020,11 @@ test_xmlUCSIsCat(void) {
code = gen_int(n_code, 0);
cat = gen_const_char_ptr(n_cat, 1);
- ret_val = xmlUCSIsCat(code, (const char *)cat);
+ ret_val = xmlUCSIsCat(code, cat);
desret_int(ret_val);
call_tests++;
des_int(n_code, code, 0);
- des_const_char_ptr(n_cat, (const char *)cat, 1);
+ des_const_char_ptr(n_cat, cat, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlUCSIsCat",
@@ -43178,6 +44152,40 @@ test_xmlNewTextWriterTree(void) {
}
+static int
+test_xmlTextWriterClose(void) {
+ int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+ int mem_base;
+ int ret_val;
+ xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+ int n_writer;
+
+ for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+ mem_base = xmlMemBlocks();
+ writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+ ret_val = xmlTextWriterClose(writer);
+ desret_int(ret_val);
+ call_tests++;
+ des_xmlTextWriterPtr(n_writer, writer, 0);
+ xmlResetLastError();
+ if (mem_base != xmlMemBlocks()) {
+ printf("Leak of %d blocks found in xmlTextWriterClose",
+ xmlMemBlocks() - mem_base);
+ test_ret++;
+ printf(" %d", n_writer);
+ printf("\n");
+ }
+ }
+ function_tests++;
+#endif
+
+ return(test_ret);
+}
+
+
static int
test_xmlTextWriterEndAttribute(void) {
int test_ret = 0;
@@ -43636,7 +44644,7 @@ test_xmlTextWriterSetIndentString(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * str; /* the xmlChar string */
+ const xmlChar * str; /* the xmlChar string */
int n_str;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -43645,11 +44653,11 @@ test_xmlTextWriterSetIndentString(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
str = gen_const_xmlChar_ptr(n_str, 1);
- ret_val = xmlTextWriterSetIndentString(writer, (const xmlChar *)str);
+ ret_val = xmlTextWriterSetIndentString(writer, str);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterSetIndentString",
@@ -43718,7 +44726,7 @@ test_xmlTextWriterStartAttribute(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* element name */
+ const xmlChar * name; /* element name */
int n_name;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -43727,11 +44735,11 @@ test_xmlTextWriterStartAttribute(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlTextWriterStartAttribute(writer, (const xmlChar *)name);
+ ret_val = xmlTextWriterStartAttribute(writer, name);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartAttribute",
@@ -43759,11 +44767,11 @@ test_xmlTextWriterStartAttributeNS(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * prefix; /* namespace prefix or NULL */
+ const xmlChar * prefix; /* namespace prefix or NULL */
int n_prefix;
- xmlChar * name; /* element local name */
+ const xmlChar * name; /* element local name */
int n_name;
- xmlChar * namespaceURI; /* namespace URI or NULL */
+ const xmlChar * namespaceURI; /* namespace URI or NULL */
int n_namespaceURI;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -43776,13 +44784,13 @@ test_xmlTextWriterStartAttributeNS(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 3);
- ret_val = xmlTextWriterStartAttributeNS(writer, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)namespaceURI);
+ ret_val = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 3);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_namespaceURI, namespaceURI, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartAttributeNS",
@@ -43882,11 +44890,11 @@ test_xmlTextWriterStartDTD(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* the name of the DTD */
+ const xmlChar * name; /* the name of the DTD */
int n_name;
- xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+ const xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
int n_pubid;
- xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+ const xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
int n_sysid;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -43899,13 +44907,13 @@ test_xmlTextWriterStartDTD(void) {
pubid = gen_const_xmlChar_ptr(n_pubid, 2);
sysid = gen_const_xmlChar_ptr(n_sysid, 3);
- ret_val = xmlTextWriterStartDTD(writer, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid);
+ ret_val = xmlTextWriterStartDTD(writer, name, pubid, sysid);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 2);
- des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 3);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_pubid, pubid, 2);
+ des_const_xmlChar_ptr(n_sysid, sysid, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartDTD",
@@ -43937,7 +44945,7 @@ test_xmlTextWriterStartDTDAttlist(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* the name of the DTD ATTLIST */
+ const xmlChar * name; /* the name of the DTD ATTLIST */
int n_name;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -43946,11 +44954,11 @@ test_xmlTextWriterStartDTDAttlist(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlTextWriterStartDTDAttlist(writer, (const xmlChar *)name);
+ ret_val = xmlTextWriterStartDTDAttlist(writer, name);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartDTDAttlist",
@@ -43978,7 +44986,7 @@ test_xmlTextWriterStartDTDElement(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* the name of the DTD element */
+ const xmlChar * name; /* the name of the DTD element */
int n_name;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -43987,11 +44995,11 @@ test_xmlTextWriterStartDTDElement(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlTextWriterStartDTDElement(writer, (const xmlChar *)name);
+ ret_val = xmlTextWriterStartDTDElement(writer, name);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartDTDElement",
@@ -44021,7 +45029,7 @@ test_xmlTextWriterStartDTDEntity(void) {
int n_writer;
int pe; /* TRUE if this is a parameter entity, FALSE if not */
int n_pe;
- xmlChar * name; /* the name of the DTD ATTLIST */
+ const xmlChar * name; /* the name of the DTD ATTLIST */
int n_name;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44032,12 +45040,12 @@ test_xmlTextWriterStartDTDEntity(void) {
pe = gen_int(n_pe, 1);
name = gen_const_xmlChar_ptr(n_name, 2);
- ret_val = xmlTextWriterStartDTDEntity(writer, pe, (const xmlChar *)name);
+ ret_val = xmlTextWriterStartDTDEntity(writer, pe, name);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
des_int(n_pe, pe, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+ des_const_xmlChar_ptr(n_name, name, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartDTDEntity",
@@ -44067,11 +45075,11 @@ test_xmlTextWriterStartDocument(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- char * version; /* the xml version ("1.0") or NULL for default ("1.0") */
+ const char * version; /* the xml version ("1.0") or NULL for default ("1.0") */
int n_version;
- char * encoding; /* the encoding or NULL for default */
+ const char * encoding; /* the encoding or NULL for default */
int n_encoding;
- char * standalone; /* "yes" or "no" or NULL for default */
+ const char * standalone; /* "yes" or "no" or NULL for default */
int n_standalone;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44084,13 +45092,13 @@ test_xmlTextWriterStartDocument(void) {
encoding = gen_const_char_ptr(n_encoding, 2);
standalone = gen_const_char_ptr(n_standalone, 3);
- ret_val = xmlTextWriterStartDocument(writer, (const char *)version, (const char *)encoding, (const char *)standalone);
+ ret_val = xmlTextWriterStartDocument(writer, version, encoding, standalone);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_char_ptr(n_version, (const char *)version, 1);
- des_const_char_ptr(n_encoding, (const char *)encoding, 2);
- des_const_char_ptr(n_standalone, (const char *)standalone, 3);
+ des_const_char_ptr(n_version, version, 1);
+ des_const_char_ptr(n_encoding, encoding, 2);
+ des_const_char_ptr(n_standalone, standalone, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartDocument",
@@ -44122,7 +45130,7 @@ test_xmlTextWriterStartElement(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* element name */
+ const xmlChar * name; /* element name */
int n_name;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44131,11 +45139,11 @@ test_xmlTextWriterStartElement(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlTextWriterStartElement(writer, (const xmlChar *)name);
+ ret_val = xmlTextWriterStartElement(writer, name);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartElement",
@@ -44163,11 +45171,11 @@ test_xmlTextWriterStartElementNS(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * prefix; /* namespace prefix or NULL */
+ const xmlChar * prefix; /* namespace prefix or NULL */
int n_prefix;
- xmlChar * name; /* element local name */
+ const xmlChar * name; /* element local name */
int n_name;
- xmlChar * namespaceURI; /* namespace URI or NULL */
+ const xmlChar * namespaceURI; /* namespace URI or NULL */
int n_namespaceURI;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44180,13 +45188,13 @@ test_xmlTextWriterStartElementNS(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 3);
- ret_val = xmlTextWriterStartElementNS(writer, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)namespaceURI);
+ ret_val = xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 3);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_namespaceURI, namespaceURI, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartElementNS",
@@ -44218,7 +45226,7 @@ test_xmlTextWriterStartPI(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * target; /* PI target */
+ const xmlChar * target; /* PI target */
int n_target;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44227,11 +45235,11 @@ test_xmlTextWriterStartPI(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
target = gen_const_xmlChar_ptr(n_target, 1);
- ret_val = xmlTextWriterStartPI(writer, (const xmlChar *)target);
+ ret_val = xmlTextWriterStartPI(writer, target);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_target, (const xmlChar *)target, 1);
+ des_const_xmlChar_ptr(n_target, target, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterStartPI",
@@ -44259,9 +45267,9 @@ test_xmlTextWriterWriteAttribute(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* attribute name */
+ const xmlChar * name; /* attribute name */
int n_name;
- xmlChar * content; /* attribute content */
+ const xmlChar * content; /* attribute content */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44272,12 +45280,12 @@ test_xmlTextWriterWriteAttribute(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
content = gen_const_xmlChar_ptr(n_content, 2);
- ret_val = xmlTextWriterWriteAttribute(writer, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteAttribute(writer, name, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_content, content, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteAttribute",
@@ -44307,13 +45315,13 @@ test_xmlTextWriterWriteAttributeNS(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * prefix; /* namespace prefix */
+ const xmlChar * prefix; /* namespace prefix */
int n_prefix;
- xmlChar * name; /* attribute local name */
+ const xmlChar * name; /* attribute local name */
int n_name;
- xmlChar * namespaceURI; /* namespace URI */
+ const xmlChar * namespaceURI; /* namespace URI */
int n_namespaceURI;
- xmlChar * content; /* attribute content */
+ const xmlChar * content; /* attribute content */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44328,14 +45336,14 @@ test_xmlTextWriterWriteAttributeNS(void) {
namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 3);
content = gen_const_xmlChar_ptr(n_content, 4);
- ret_val = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)namespaceURI, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 3);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 4);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_namespaceURI, namespaceURI, 3);
+ des_const_xmlChar_ptr(n_content, content, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteAttributeNS",
@@ -44369,7 +45377,7 @@ test_xmlTextWriterWriteBase64(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- char * data; /* binary data */
+ const char * data; /* binary data */
int n_data;
int start; /* the position within the data of the first byte to encode */
int n_start;
@@ -44392,11 +45400,11 @@ test_xmlTextWriterWriteBase64(void) {
(len > xmlStrlen(BAD_CAST data)))
len = 0;
- ret_val = xmlTextWriterWriteBase64(writer, (const char *)data, start, len);
+ ret_val = xmlTextWriterWriteBase64(writer, data, start, len);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_char_ptr(n_data, (const char *)data, 1);
+ des_const_char_ptr(n_data, data, 1);
des_int(n_start, start, 2);
des_int(n_len, len, 3);
xmlResetLastError();
@@ -44430,7 +45438,7 @@ test_xmlTextWriterWriteBinHex(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- char * data; /* binary data */
+ const char * data; /* binary data */
int n_data;
int start; /* the position within the data of the first byte to encode */
int n_start;
@@ -44453,11 +45461,11 @@ test_xmlTextWriterWriteBinHex(void) {
(len > xmlStrlen(BAD_CAST data)))
len = 0;
- ret_val = xmlTextWriterWriteBinHex(writer, (const char *)data, start, len);
+ ret_val = xmlTextWriterWriteBinHex(writer, data, start, len);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_char_ptr(n_data, (const char *)data, 1);
+ des_const_char_ptr(n_data, data, 1);
des_int(n_start, start, 2);
des_int(n_len, len, 3);
xmlResetLastError();
@@ -44491,7 +45499,7 @@ test_xmlTextWriterWriteCDATA(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * content; /* CDATA content */
+ const xmlChar * content; /* CDATA content */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44500,11 +45508,11 @@ test_xmlTextWriterWriteCDATA(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- ret_val = xmlTextWriterWriteCDATA(writer, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteCDATA(writer, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteCDATA",
@@ -44532,7 +45540,7 @@ test_xmlTextWriterWriteComment(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * content; /* comment string */
+ const xmlChar * content; /* comment string */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44541,11 +45549,11 @@ test_xmlTextWriterWriteComment(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- ret_val = xmlTextWriterWriteComment(writer, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteComment(writer, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteComment",
@@ -44573,13 +45581,13 @@ test_xmlTextWriterWriteDTD(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* the name of the DTD */
+ const xmlChar * name; /* the name of the DTD */
int n_name;
- xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+ const xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
int n_pubid;
- xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+ const xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
int n_sysid;
- xmlChar * subset; /* string content of the DTD */
+ const xmlChar * subset; /* string content of the DTD */
int n_subset;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44594,14 +45602,14 @@ test_xmlTextWriterWriteDTD(void) {
sysid = gen_const_xmlChar_ptr(n_sysid, 3);
subset = gen_const_xmlChar_ptr(n_subset, 4);
- ret_val = xmlTextWriterWriteDTD(writer, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid, (const xmlChar *)subset);
+ ret_val = xmlTextWriterWriteDTD(writer, name, pubid, sysid, subset);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 2);
- des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 3);
- des_const_xmlChar_ptr(n_subset, (const xmlChar *)subset, 4);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_pubid, pubid, 2);
+ des_const_xmlChar_ptr(n_sysid, sysid, 3);
+ des_const_xmlChar_ptr(n_subset, subset, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteDTD",
@@ -44635,9 +45643,9 @@ test_xmlTextWriterWriteDTDAttlist(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* the name of the DTD ATTLIST */
+ const xmlChar * name; /* the name of the DTD ATTLIST */
int n_name;
- xmlChar * content; /* content of the ATTLIST */
+ const xmlChar * content; /* content of the ATTLIST */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44648,12 +45656,12 @@ test_xmlTextWriterWriteDTDAttlist(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
content = gen_const_xmlChar_ptr(n_content, 2);
- ret_val = xmlTextWriterWriteDTDAttlist(writer, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteDTDAttlist(writer, name, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_content, content, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteDTDAttlist",
@@ -44683,9 +45691,9 @@ test_xmlTextWriterWriteDTDElement(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* the name of the DTD element */
+ const xmlChar * name; /* the name of the DTD element */
int n_name;
- xmlChar * content; /* content of the element */
+ const xmlChar * content; /* content of the element */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44696,12 +45704,12 @@ test_xmlTextWriterWriteDTDElement(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
content = gen_const_xmlChar_ptr(n_content, 2);
- ret_val = xmlTextWriterWriteDTDElement(writer, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteDTDElement(writer, name, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_content, content, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteDTDElement",
@@ -44733,15 +45741,15 @@ test_xmlTextWriterWriteDTDEntity(void) {
int n_writer;
int pe; /* TRUE if this is a parameter entity, FALSE if not */
int n_pe;
- xmlChar * name; /* the name of the DTD entity */
+ const xmlChar * name; /* the name of the DTD entity */
int n_name;
- xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+ const xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
int n_pubid;
- xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+ const xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
int n_sysid;
- xmlChar * ndataid; /* the xml notation name. */
+ const xmlChar * ndataid; /* the xml notation name. */
int n_ndataid;
- xmlChar * content; /* content of the entity */
+ const xmlChar * content; /* content of the entity */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44760,16 +45768,16 @@ test_xmlTextWriterWriteDTDEntity(void) {
ndataid = gen_const_xmlChar_ptr(n_ndataid, 5);
content = gen_const_xmlChar_ptr(n_content, 6);
- ret_val = xmlTextWriterWriteDTDEntity(writer, pe, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid, (const xmlChar *)ndataid, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteDTDEntity(writer, pe, name, pubid, sysid, ndataid, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
des_int(n_pe, pe, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 3);
- des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 4);
- des_const_xmlChar_ptr(n_ndataid, (const xmlChar *)ndataid, 5);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 6);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_pubid, pubid, 3);
+ des_const_xmlChar_ptr(n_sysid, sysid, 4);
+ des_const_xmlChar_ptr(n_ndataid, ndataid, 5);
+ des_const_xmlChar_ptr(n_content, content, 6);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteDTDEntity",
@@ -44809,13 +45817,13 @@ test_xmlTextWriterWriteDTDExternalEntity(void) {
int n_writer;
int pe; /* TRUE if this is a parameter entity, FALSE if not */
int n_pe;
- xmlChar * name; /* the name of the DTD entity */
+ const xmlChar * name; /* the name of the DTD entity */
int n_name;
- xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+ const xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
int n_pubid;
- xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+ const xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
int n_sysid;
- xmlChar * ndataid; /* the xml notation name. */
+ const xmlChar * ndataid; /* the xml notation name. */
int n_ndataid;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44832,15 +45840,15 @@ test_xmlTextWriterWriteDTDExternalEntity(void) {
sysid = gen_const_xmlChar_ptr(n_sysid, 4);
ndataid = gen_const_xmlChar_ptr(n_ndataid, 5);
- ret_val = xmlTextWriterWriteDTDExternalEntity(writer, pe, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid, (const xmlChar *)ndataid);
+ ret_val = xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid, sysid, ndataid);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
des_int(n_pe, pe, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 3);
- des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 4);
- des_const_xmlChar_ptr(n_ndataid, (const xmlChar *)ndataid, 5);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_pubid, pubid, 3);
+ des_const_xmlChar_ptr(n_sysid, sysid, 4);
+ des_const_xmlChar_ptr(n_ndataid, ndataid, 5);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteDTDExternalEntity",
@@ -44876,11 +45884,11 @@ test_xmlTextWriterWriteDTDExternalEntityContents(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+ const xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
int n_pubid;
- xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+ const xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
int n_sysid;
- xmlChar * ndataid; /* the xml notation name. */
+ const xmlChar * ndataid; /* the xml notation name. */
int n_ndataid;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44893,13 +45901,13 @@ test_xmlTextWriterWriteDTDExternalEntityContents(void) {
sysid = gen_const_xmlChar_ptr(n_sysid, 2);
ndataid = gen_const_xmlChar_ptr(n_ndataid, 3);
- ret_val = xmlTextWriterWriteDTDExternalEntityContents(writer, (const xmlChar *)pubid, (const xmlChar *)sysid, (const xmlChar *)ndataid);
+ ret_val = xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid, ndataid);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 1);
- des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 2);
- des_const_xmlChar_ptr(n_ndataid, (const xmlChar *)ndataid, 3);
+ des_const_xmlChar_ptr(n_pubid, pubid, 1);
+ des_const_xmlChar_ptr(n_sysid, sysid, 2);
+ des_const_xmlChar_ptr(n_ndataid, ndataid, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteDTDExternalEntityContents",
@@ -44933,9 +45941,9 @@ test_xmlTextWriterWriteDTDInternalEntity(void) {
int n_writer;
int pe; /* TRUE if this is a parameter entity, FALSE if not */
int n_pe;
- xmlChar * name; /* the name of the DTD entity */
+ const xmlChar * name; /* the name of the DTD entity */
int n_name;
- xmlChar * content; /* content of the entity */
+ const xmlChar * content; /* content of the entity */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -44948,13 +45956,13 @@ test_xmlTextWriterWriteDTDInternalEntity(void) {
name = gen_const_xmlChar_ptr(n_name, 2);
content = gen_const_xmlChar_ptr(n_content, 3);
- ret_val = xmlTextWriterWriteDTDInternalEntity(writer, pe, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
des_int(n_pe, pe, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_content, content, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteDTDInternalEntity",
@@ -44986,11 +45994,11 @@ test_xmlTextWriterWriteDTDNotation(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* the name of the xml notation */
+ const xmlChar * name; /* the name of the xml notation */
int n_name;
- xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+ const xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
int n_pubid;
- xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+ const xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
int n_sysid;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -45003,13 +46011,13 @@ test_xmlTextWriterWriteDTDNotation(void) {
pubid = gen_const_xmlChar_ptr(n_pubid, 2);
sysid = gen_const_xmlChar_ptr(n_sysid, 3);
- ret_val = xmlTextWriterWriteDTDNotation(writer, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid);
+ ret_val = xmlTextWriterWriteDTDNotation(writer, name, pubid, sysid);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 2);
- des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 3);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_pubid, pubid, 2);
+ des_const_xmlChar_ptr(n_sysid, sysid, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteDTDNotation",
@@ -45041,9 +46049,9 @@ test_xmlTextWriterWriteElement(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * name; /* element name */
+ const xmlChar * name; /* element name */
int n_name;
- xmlChar * content; /* element content */
+ const xmlChar * content; /* element content */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -45054,12 +46062,12 @@ test_xmlTextWriterWriteElement(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
content = gen_const_xmlChar_ptr(n_content, 2);
- ret_val = xmlTextWriterWriteElement(writer, (const xmlChar *)name, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteElement(writer, name, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_content, content, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteElement",
@@ -45089,13 +46097,13 @@ test_xmlTextWriterWriteElementNS(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * prefix; /* namespace prefix */
+ const xmlChar * prefix; /* namespace prefix */
int n_prefix;
- xmlChar * name; /* element local name */
+ const xmlChar * name; /* element local name */
int n_name;
- xmlChar * namespaceURI; /* namespace URI */
+ const xmlChar * namespaceURI; /* namespace URI */
int n_namespaceURI;
- xmlChar * content; /* element content */
+ const xmlChar * content; /* element content */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -45110,14 +46118,14 @@ test_xmlTextWriterWriteElementNS(void) {
namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 3);
content = gen_const_xmlChar_ptr(n_content, 4);
- ret_val = xmlTextWriterWriteElementNS(writer, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)namespaceURI, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
- des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 3);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 4);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
+ des_const_xmlChar_ptr(n_name, name, 2);
+ des_const_xmlChar_ptr(n_namespaceURI, namespaceURI, 3);
+ des_const_xmlChar_ptr(n_content, content, 4);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteElementNS",
@@ -45281,9 +46289,9 @@ test_xmlTextWriterWritePI(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * target; /* PI target */
+ const xmlChar * target; /* PI target */
int n_target;
- xmlChar * content; /* PI content */
+ const xmlChar * content; /* PI content */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -45294,12 +46302,12 @@ test_xmlTextWriterWritePI(void) {
target = gen_const_xmlChar_ptr(n_target, 1);
content = gen_const_xmlChar_ptr(n_content, 2);
- ret_val = xmlTextWriterWritePI(writer, (const xmlChar *)target, (const xmlChar *)content);
+ ret_val = xmlTextWriterWritePI(writer, target, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_target, (const xmlChar *)target, 1);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+ des_const_xmlChar_ptr(n_target, target, 1);
+ des_const_xmlChar_ptr(n_content, content, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWritePI",
@@ -45329,7 +46337,7 @@ test_xmlTextWriterWriteRaw(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * content; /* text string */
+ const xmlChar * content; /* text string */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -45338,11 +46346,11 @@ test_xmlTextWriterWriteRaw(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- ret_val = xmlTextWriterWriteRaw(writer, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteRaw(writer, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteRaw",
@@ -45370,7 +46378,7 @@ test_xmlTextWriterWriteRawLen(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * content; /* text string */
+ const xmlChar * content; /* text string */
int n_content;
int len; /* length of the text string */
int n_len;
@@ -45386,11 +46394,11 @@ test_xmlTextWriterWriteRawLen(void) {
(len > xmlStrlen(BAD_CAST content)))
len = 0;
- ret_val = xmlTextWriterWriteRawLen(writer, (const xmlChar *)content, len);
+ ret_val = xmlTextWriterWriteRawLen(writer, content, len);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
des_int(n_len, len, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -45421,7 +46429,7 @@ test_xmlTextWriterWriteString(void) {
int ret_val;
xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
int n_writer;
- xmlChar * content; /* text string */
+ const xmlChar * content; /* text string */
int n_content;
for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
@@ -45430,11 +46438,11 @@ test_xmlTextWriterWriteString(void) {
writer = gen_xmlTextWriterPtr(n_writer, 0);
content = gen_const_xmlChar_ptr(n_content, 1);
- ret_val = xmlTextWriterWriteString(writer, (const xmlChar *)content);
+ ret_val = xmlTextWriterWriteString(writer, content);
desret_int(ret_val);
call_tests++;
des_xmlTextWriterPtr(n_writer, writer, 0);
- des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+ des_const_xmlChar_ptr(n_content, content, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlTextWriterWriteString",
@@ -45586,12 +46594,13 @@ static int
test_xmlwriter(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing xmlwriter : 52 of 80 functions ...\n");
+ if (quiet == 0) printf("Testing xmlwriter : 53 of 81 functions ...\n");
test_ret += test_xmlNewTextWriter();
test_ret += test_xmlNewTextWriterFilename();
test_ret += test_xmlNewTextWriterMemory();
test_ret += test_xmlNewTextWriterPushParser();
test_ret += test_xmlNewTextWriterTree();
+ test_ret += test_xmlTextWriterClose();
test_ret += test_xmlTextWriterEndAttribute();
test_ret += test_xmlTextWriterEndCDATA();
test_ret += test_xmlTextWriterEndComment();
@@ -45984,17 +46993,17 @@ test_xmlXPathCastStringToBoolean(void) {
#if defined(LIBXML_XPATH_ENABLED)
int mem_base;
int ret_val;
- xmlChar * val; /* a string */
+ const xmlChar * val; /* a string */
int n_val;
for (n_val = 0;n_val < gen_nb_const_xmlChar_ptr;n_val++) {
mem_base = xmlMemBlocks();
val = gen_const_xmlChar_ptr(n_val, 0);
- ret_val = xmlXPathCastStringToBoolean((const xmlChar *)val);
+ ret_val = xmlXPathCastStringToBoolean(val);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 0);
+ des_const_xmlChar_ptr(n_val, val, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathCastStringToBoolean",
@@ -46018,17 +47027,17 @@ test_xmlXPathCastStringToNumber(void) {
#if defined(LIBXML_XPATH_ENABLED)
int mem_base;
double ret_val;
- xmlChar * val; /* a string */
+ const xmlChar * val; /* a string */
int n_val;
for (n_val = 0;n_val < gen_nb_const_xmlChar_ptr;n_val++) {
mem_base = xmlMemBlocks();
val = gen_const_xmlChar_ptr(n_val, 0);
- ret_val = xmlXPathCastStringToNumber((const xmlChar *)val);
+ ret_val = xmlXPathCastStringToNumber(val);
desret_double(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 0);
+ des_const_xmlChar_ptr(n_val, val, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathCastStringToNumber",
@@ -46471,7 +47480,7 @@ test_xmlXPathEval(void) {
#if defined(LIBXML_XPATH_ENABLED)
int mem_base;
xmlXPathObjectPtr ret_val;
- xmlChar * str; /* the XPath expression */
+ const xmlChar * str; /* the XPath expression */
int n_str;
xmlXPathContextPtr ctx; /* the XPath context */
int n_ctx;
@@ -46482,10 +47491,10 @@ test_xmlXPathEval(void) {
str = gen_const_xmlChar_ptr(n_str, 0);
ctx = gen_xmlXPathContextPtr(n_ctx, 1);
- ret_val = xmlXPathEval((const xmlChar *)str, ctx);
+ ret_val = xmlXPathEval(str, ctx);
desret_xmlXPathObjectPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+ des_const_xmlChar_ptr(n_str, str, 0);
des_xmlXPathContextPtr(n_ctx, ctx, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -46512,7 +47521,7 @@ test_xmlXPathEvalExpression(void) {
#if defined(LIBXML_XPATH_ENABLED)
int mem_base;
xmlXPathObjectPtr ret_val;
- xmlChar * str; /* the XPath expression */
+ const xmlChar * str; /* the XPath expression */
int n_str;
xmlXPathContextPtr ctxt; /* the XPath context */
int n_ctxt;
@@ -46523,10 +47532,10 @@ test_xmlXPathEvalExpression(void) {
str = gen_const_xmlChar_ptr(n_str, 0);
ctxt = gen_xmlXPathContextPtr(n_ctxt, 1);
- ret_val = xmlXPathEvalExpression((const xmlChar *)str, ctxt);
+ ret_val = xmlXPathEvalExpression(str, ctxt);
desret_xmlXPathObjectPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+ des_const_xmlChar_ptr(n_str, str, 0);
des_xmlXPathContextPtr(n_ctxt, ctxt, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -46699,7 +47708,7 @@ test_xmlXPathNodeEval(void) {
xmlXPathObjectPtr ret_val;
xmlNodePtr node; /* the node to to use as the context node */
int n_node;
- xmlChar * str; /* the XPath expression */
+ const xmlChar * str; /* the XPath expression */
int n_str;
xmlXPathContextPtr ctx; /* the XPath context */
int n_ctx;
@@ -46712,11 +47721,11 @@ test_xmlXPathNodeEval(void) {
str = gen_const_xmlChar_ptr(n_str, 1);
ctx = gen_xmlXPathContextPtr(n_ctx, 2);
- ret_val = xmlXPathNodeEval(node, (const xmlChar *)str, ctx);
+ ret_val = xmlXPathNodeEval(node, str, ctx);
desret_xmlXPathObjectPtr(ret_val);
call_tests++;
des_xmlNodePtr(n_node, node, 0);
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+ des_const_xmlChar_ptr(n_str, str, 1);
des_xmlXPathContextPtr(n_ctx, ctx, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -46880,11 +47889,21 @@ test_xmlXPathSetContextNode(void) {
return(test_ret);
}
+
+static int
+test_xmlXPathSetErrorHandler(void) {
+ int test_ret = 0;
+
+
+ /* missing type support */
+ return(test_ret);
+}
+
static int
test_xpath(void) {
int test_ret = 0;
- if (quiet == 0) printf("Testing xpath : 32 of 40 functions ...\n");
+ if (quiet == 0) printf("Testing xpath : 32 of 41 functions ...\n");
test_ret += test_xmlXPathCastBooleanToNumber();
test_ret += test_xmlXPathCastBooleanToString();
test_ret += test_xmlXPathCastNodeSetToBoolean();
@@ -46920,6 +47939,7 @@ test_xpath(void) {
test_ret += test_xmlXPathObjectCopy();
test_ret += test_xmlXPathOrderDocElems();
test_ret += test_xmlXPathSetContextNode();
+ test_ret += test_xmlXPathSetErrorHandler();
if (test_ret != 0)
printf("Module xpath: %d errors\n", test_ret);
@@ -47558,26 +48578,26 @@ test_xmlXPathErr(void) {
int mem_base;
xmlXPathParserContextPtr ctxt; /* a XPath parser context */
int n_ctxt;
- int error; /* the error code */
- int n_error;
+ int code; /* the error code */
+ int n_code;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
- for (n_error = 0;n_error < gen_nb_int;n_error++) {
+ for (n_code = 0;n_code < gen_nb_int;n_code++) {
mem_base = xmlMemBlocks();
ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
- error = gen_int(n_error, 1);
+ code = gen_int(n_code, 1);
- xmlXPathErr(ctxt, error);
+ xmlXPathErr(ctxt, code);
call_tests++;
des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
- des_int(n_error, error, 1);
+ des_int(n_code, code, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathErr",
xmlMemBlocks() - mem_base);
test_ret++;
printf(" %d", n_ctxt);
- printf(" %d", n_error);
+ printf(" %d", n_code);
printf("\n");
}
}
@@ -47888,17 +48908,17 @@ test_xmlXPathIsNodeType(void) {
#if defined(LIBXML_XPATH_ENABLED)
int mem_base;
int ret_val;
- xmlChar * name; /* a name string */
+ const xmlChar * name; /* a name string */
int n_name;
for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
mem_base = xmlMemBlocks();
name = gen_const_xmlChar_ptr(n_name, 0);
- ret_val = xmlXPathIsNodeType((const xmlChar *)name);
+ ret_val = xmlXPathIsNodeType(name);
desret_int(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+ des_const_xmlChar_ptr(n_name, name, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathIsNodeType",
@@ -48258,17 +49278,17 @@ test_xmlXPathNewCString(void) {
#if defined(LIBXML_XPATH_ENABLED)
int mem_base;
xmlXPathObjectPtr ret_val;
- char * val; /* the char * value */
+ const char * val; /* the char * value */
int n_val;
for (n_val = 0;n_val < gen_nb_const_char_ptr;n_val++) {
mem_base = xmlMemBlocks();
val = gen_const_char_ptr(n_val, 0);
- ret_val = xmlXPathNewCString((const char *)val);
+ ret_val = xmlXPathNewCString(val);
desret_xmlXPathObjectPtr(ret_val);
call_tests++;
- des_const_char_ptr(n_val, (const char *)val, 0);
+ des_const_char_ptr(n_val, val, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathNewCString",
@@ -48404,17 +49424,17 @@ test_xmlXPathNewString(void) {
#if defined(LIBXML_XPATH_ENABLED)
int mem_base;
xmlXPathObjectPtr ret_val;
- xmlChar * val; /* the xmlChar * value */
+ const xmlChar * val; /* the xmlChar * value */
int n_val;
for (n_val = 0;n_val < gen_nb_const_xmlChar_ptr;n_val++) {
mem_base = xmlMemBlocks();
val = gen_const_xmlChar_ptr(n_val, 0);
- ret_val = xmlXPathNewString((const xmlChar *)val);
+ ret_val = xmlXPathNewString(val);
desret_xmlXPathObjectPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 0);
+ des_const_xmlChar_ptr(n_val, val, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathNewString",
@@ -49571,7 +50591,7 @@ test_xmlXPathNsLookup(void) {
const xmlChar * ret_val;
xmlXPathContextPtr ctxt; /* the XPath context */
int n_ctxt;
- xmlChar * prefix; /* the namespace prefix value */
+ const xmlChar * prefix; /* the namespace prefix value */
int n_prefix;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
@@ -49580,11 +50600,11 @@ test_xmlXPathNsLookup(void) {
ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
prefix = gen_const_xmlChar_ptr(n_prefix, 1);
- ret_val = xmlXPathNsLookup(ctxt, (const xmlChar *)prefix);
+ ret_val = xmlXPathNsLookup(ctxt, prefix);
desret_const_xmlChar_ptr(ret_val);
call_tests++;
des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathNsLookup",
@@ -49990,9 +51010,9 @@ test_xmlXPathRegisterNs(void) {
int ret_val;
xmlXPathContextPtr ctxt; /* the XPath context */
int n_ctxt;
- xmlChar * prefix; /* the namespace prefix cannot be NULL or empty string */
+ const xmlChar * prefix; /* the namespace prefix cannot be NULL or empty string */
int n_prefix;
- xmlChar * ns_uri; /* the namespace name */
+ const xmlChar * ns_uri; /* the namespace name */
int n_ns_uri;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
@@ -50003,12 +51023,12 @@ test_xmlXPathRegisterNs(void) {
prefix = gen_const_xmlChar_ptr(n_prefix, 1);
ns_uri = gen_const_xmlChar_ptr(n_ns_uri, 2);
- ret_val = xmlXPathRegisterNs(ctxt, (const xmlChar *)prefix, (const xmlChar *)ns_uri);
+ ret_val = xmlXPathRegisterNs(ctxt, prefix, ns_uri);
desret_int(ret_val);
call_tests++;
des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
- des_const_xmlChar_ptr(n_ns_uri, (const xmlChar *)ns_uri, 2);
+ des_const_xmlChar_ptr(n_prefix, prefix, 1);
+ des_const_xmlChar_ptr(n_ns_uri, ns_uri, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathRegisterNs",
@@ -50038,7 +51058,7 @@ test_xmlXPathRegisterVariable(void) {
int ret_val;
xmlXPathContextPtr ctxt; /* the XPath context */
int n_ctxt;
- xmlChar * name; /* the variable name */
+ const xmlChar * name; /* the variable name */
int n_name;
xmlXPathObjectPtr value; /* the variable value or NULL */
int n_value;
@@ -50051,11 +51071,11 @@ test_xmlXPathRegisterVariable(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
value = gen_xmlXPathObjectPtr(n_value, 2);
- ret_val = xmlXPathRegisterVariable(ctxt, (const xmlChar *)name, value);
+ ret_val = xmlXPathRegisterVariable(ctxt, name, value);
desret_int(ret_val);
call_tests++;
des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
des_xmlXPathObjectPtr(n_value, value, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -50096,9 +51116,9 @@ test_xmlXPathRegisterVariableNS(void) {
int ret_val;
xmlXPathContextPtr ctxt; /* the XPath context */
int n_ctxt;
- xmlChar * name; /* the variable name */
+ const xmlChar * name; /* the variable name */
int n_name;
- xmlChar * ns_uri; /* the variable namespace URI */
+ const xmlChar * ns_uri; /* the variable namespace URI */
int n_ns_uri;
xmlXPathObjectPtr value; /* the variable value or NULL */
int n_value;
@@ -50113,12 +51133,12 @@ test_xmlXPathRegisterVariableNS(void) {
ns_uri = gen_const_xmlChar_ptr(n_ns_uri, 2);
value = gen_xmlXPathObjectPtr(n_value, 3);
- ret_val = xmlXPathRegisterVariableNS(ctxt, (const xmlChar *)name, (const xmlChar *)ns_uri, value);
+ ret_val = xmlXPathRegisterVariableNS(ctxt, name, ns_uri, value);
desret_int(ret_val);
call_tests++;
des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_ns_uri, (const xmlChar *)ns_uri, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_ns_uri, ns_uri, 2);
des_xmlXPathObjectPtr(n_value, value, 3);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
@@ -50355,17 +51375,17 @@ test_xmlXPathStringEvalNumber(void) {
#if defined(LIBXML_XPATH_ENABLED)
int mem_base;
double ret_val;
- xmlChar * str; /* A string to scan */
+ const xmlChar * str; /* A string to scan */
int n_str;
for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
mem_base = xmlMemBlocks();
str = gen_const_xmlChar_ptr(n_str, 0);
- ret_val = xmlXPathStringEvalNumber((const xmlChar *)str);
+ ret_val = xmlXPathStringEvalNumber(str);
desret_double(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+ des_const_xmlChar_ptr(n_str, str, 0);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathStringEvalNumber",
@@ -50849,7 +51869,7 @@ test_xmlXPathVariableLookup(void) {
xmlXPathObjectPtr ret_val;
xmlXPathContextPtr ctxt; /* the XPath context */
int n_ctxt;
- xmlChar * name; /* the variable name */
+ const xmlChar * name; /* the variable name */
int n_name;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
@@ -50858,11 +51878,11 @@ test_xmlXPathVariableLookup(void) {
ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
name = gen_const_xmlChar_ptr(n_name, 1);
- ret_val = xmlXPathVariableLookup(ctxt, (const xmlChar *)name);
+ ret_val = xmlXPathVariableLookup(ctxt, name);
desret_xmlXPathObjectPtr(ret_val);
call_tests++;
des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+ des_const_xmlChar_ptr(n_name, name, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathVariableLookup",
@@ -50890,9 +51910,9 @@ test_xmlXPathVariableLookupNS(void) {
xmlXPathObjectPtr ret_val;
xmlXPathContextPtr ctxt; /* the XPath context */
int n_ctxt;
- xmlChar * name; /* the variable name */
+ const xmlChar * name; /* the variable name */
int n_name;
- xmlChar * ns_uri; /* the variable namespace URI */
+ const xmlChar * ns_uri; /* the variable namespace URI */
int n_ns_uri;
for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
@@ -50903,12 +51923,12 @@ test_xmlXPathVariableLookupNS(void) {
name = gen_const_xmlChar_ptr(n_name, 1);
ns_uri = gen_const_xmlChar_ptr(n_ns_uri, 2);
- ret_val = xmlXPathVariableLookupNS(ctxt, (const xmlChar *)name, (const xmlChar *)ns_uri);
+ ret_val = xmlXPathVariableLookupNS(ctxt, name, ns_uri);
desret_xmlXPathObjectPtr(ret_val);
call_tests++;
des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
- des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
- des_const_xmlChar_ptr(n_ns_uri, (const xmlChar *)ns_uri, 2);
+ des_const_xmlChar_ptr(n_name, name, 1);
+ des_const_xmlChar_ptr(n_ns_uri, ns_uri, 2);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
printf("Leak of %d blocks found in xmlXPathVariableLookupNS",
@@ -51248,7 +52268,7 @@ test_xmlXPtrEval(void) {
#if defined(LIBXML_XPTR_ENABLED)
int mem_base;
xmlXPathObjectPtr ret_val;
- xmlChar * str; /* the XPointer expression */
+ const xmlChar * str; /* the XPointer expression */
int n_str;
xmlXPathContextPtr ctx; /* the XPointer context */
int n_ctx;
@@ -51259,10 +52279,10 @@ test_xmlXPtrEval(void) {
str = gen_const_xmlChar_ptr(n_str, 0);
ctx = gen_xmlXPathContextPtr(n_ctx, 1);
- ret_val = xmlXPtrEval((const xmlChar *)str, ctx);
+ ret_val = xmlXPtrEval(str, ctx);
desret_xmlXPathObjectPtr(ret_val);
call_tests++;
- des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+ des_const_xmlChar_ptr(n_str, str, 0);
des_xmlXPathContextPtr(n_ctx, ctx, 1);
xmlResetLastError();
if (mem_base != xmlMemBlocks()) {
diff --git a/testchar.c b/testchar.c
index f4b2f4f..13887cd 100644
--- a/testchar.c
+++ b/testchar.c
@@ -310,9 +310,9 @@ static int testCharRangeByte1(xmlParserCtxtPtr ctxt) {
c = testCurrentChar(ctxt, &len);
if (c < 0)
continue;
- if ((i == 0) || (i >= 0x80)) {
+ if (i >= 0x80) {
/* we must see an error there */
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Byte 0x%02X\n", i);
return(1);
@@ -349,7 +349,7 @@ static int testCharRangeByte2(xmlParserCtxtPtr ctxt) {
/* if first bit of first char is set, then second bit must too */
if ((i & 0x80) && ((i & 0x40) == 0)) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X\n",
i, j);
@@ -362,7 +362,7 @@ static int testCharRangeByte2(xmlParserCtxtPtr ctxt) {
* bits must be 10
*/
else if ((i & 0x80) && ((j & 0xC0) != 0x80)) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X: %d\n",
i, j, c);
@@ -375,7 +375,7 @@ static int testCharRangeByte2(xmlParserCtxtPtr ctxt) {
* than 0x80, i.e. one of bits 5 to 1 of i must be set
*/
else if ((i & 0x80) && ((i & 0x1E) == 0)) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X: %d\n",
i, j, c);
@@ -388,7 +388,7 @@ static int testCharRangeByte2(xmlParserCtxtPtr ctxt) {
* at least 3 bytes, but we give only 2 !
*/
else if ((i & 0xE0) == 0xE0) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x00\n",
i, j);
@@ -446,7 +446,7 @@ static int testCharRangeByte3(xmlParserCtxtPtr ctxt) {
* at least 4 bytes, but we give only 3 !
*/
if ((i & 0xF0) == 0xF0) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n",
i, j, K, data[3]);
@@ -458,7 +458,7 @@ static int testCharRangeByte3(xmlParserCtxtPtr ctxt) {
* The second and the third bytes must start with 10
*/
else if (((j & 0xC0) != 0x80) || ((K & 0xC0) != 0x80)) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X\n",
i, j, K);
@@ -472,7 +472,7 @@ static int testCharRangeByte3(xmlParserCtxtPtr ctxt) {
* the 6th byte of data[1] must be set
*/
else if (((i & 0xF) == 0) && ((j & 0x20) == 0)) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X\n",
i, j, K);
@@ -484,7 +484,7 @@ static int testCharRangeByte3(xmlParserCtxtPtr ctxt) {
* There are values that are not allowed in UTF-8
*/
else if ((value > 0xD7FF) && (value <0xE000)) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char 0x%04X for Bytes 0x%02X 0x%02X 0x%02X\n",
value, i, j, K);
@@ -548,7 +548,7 @@ static int testCharRangeByte4(xmlParserCtxtPtr ctxt) {
* at least 5 bytes, but we give only 4 !
*/
if ((i & 0xF8) == 0xF8) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n",
i, j, K, data[3]);
@@ -561,7 +561,7 @@ static int testCharRangeByte4(xmlParserCtxtPtr ctxt) {
*/
else if (((j & 0xC0) != 0x80) || ((K & 0xC0) != 0x80) ||
((L & 0xC0) != 0x80)) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n",
i, j, K, L);
@@ -575,7 +575,7 @@ static int testCharRangeByte4(xmlParserCtxtPtr ctxt) {
* the 6 or 5th byte of j must be set
*/
else if (((i & 0x7) == 0) && ((j & 0x30) == 0)) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n",
i, j, K, L);
@@ -588,7 +588,7 @@ static int testCharRangeByte4(xmlParserCtxtPtr ctxt) {
*/
else if (((value > 0xD7FF) && (value < 0xE000)) ||
(value > 0x10FFFF)) {
- if (lastError != XML_ERR_INVALID_CHAR) {
+ if (lastError != XML_ERR_INVALID_ENCODING) {
fprintf(stderr,
"Failed to detect invalid char 0x%04X for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n",
value, i, j, K, L);
diff --git a/testdict.c b/testdict.c
index ffbbc94..94f18c2 100644
--- a/testdict.c
+++ b/testdict.c
@@ -7,9 +7,14 @@
/**** dictionary tests ****/
#ifdef __clang__
- #define ATTRIBUTE_NO_SANITIZE_INTEGER \
- __attribute__ ((no_sanitize("unsigned-integer-overflow"))) \
- __attribute__ ((no_sanitize("unsigned-shift-base")))
+ #if __clang_major__ >= 12
+ #define ATTRIBUTE_NO_SANITIZE_INTEGER \
+ __attribute__ ((no_sanitize("unsigned-integer-overflow"))) \
+ __attribute__ ((no_sanitize("unsigned-shift-base")))
+ #else
+ #define ATTRIBUTE_NO_SANITIZE_INTEGER \
+ __attribute__ ((no_sanitize("unsigned-integer-overflow")))
+ #endif
#else
#define ATTRIBUTE_NO_SANITIZE_INTEGER
#endif
diff --git a/testlimits.c b/testlimits.c
index 78d62fb..7144b9a 100644
--- a/testlimits.c
+++ b/testlimits.c
@@ -389,279 +389,11 @@ testExternalEntityLoader(const char *URL, const char *ID,
return(ret);
}
-/*
- * Trapping the error messages at the generic level to grab the equivalent of
- * stderr messages on CLI tools.
- */
-static char testErrors[32769];
-static int testErrorsSize = 0;
-
-static void
-channel(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
- va_list args;
- int res;
-
- if (testErrorsSize >= 32768)
- return;
- va_start(args, msg);
- res = vsnprintf(&testErrors[testErrorsSize],
- 32768 - testErrorsSize,
- msg, args);
- va_end(args);
- if (testErrorsSize + res >= 32768) {
- /* buffer is full */
- testErrorsSize = 32768;
- testErrors[testErrorsSize] = 0;
- } else {
- testErrorsSize += res;
- }
- testErrors[testErrorsSize] = 0;
-}
-
-/**
- * xmlParserPrintFileContext:
- * @input: an xmlParserInputPtr input
- *
- * Displays current context within the input content for error tracking
- */
-
-static void
-xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
- xmlGenericErrorFunc chanl, void *data ) {
- const xmlChar *cur, *base;
- unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */
- xmlChar content[81]; /* space for 80 chars + line terminator */
- xmlChar *ctnt;
-
- if (input == NULL) return;
- cur = input->cur;
- base = input->base;
- /* skip backwards over any end-of-lines */
- while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
- cur--;
- }
- n = 0;
- /* search backwards for beginning-of-line (to max buff size) */
- while ((n++ < (sizeof(content)-1)) && (cur > base) &&
- (*(cur) != '\n') && (*(cur) != '\r'))
- cur--;
- if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
- /* calculate the error position in terms of the current position */
- col = input->cur - cur;
- /* search forward for end-of-line (to max buff size) */
- n = 0;
- ctnt = content;
- /* copy selected text to our buffer */
- while ((*cur != 0) && (*(cur) != '\n') &&
- (*(cur) != '\r') && (n < sizeof(content)-1)) {
- *ctnt++ = *cur++;
- n++;
- }
- *ctnt = 0;
- /* print out the selected text */
- chanl(data ,"%s\n", content);
- /* create blank line with problem pointer */
- n = 0;
- ctnt = content;
- /* (leave buffer space for pointer + line terminator) */
- while ((nfile;
- line = err->line;
- code = err->code;
- domain = err->domain;
- level = err->level;
- node = err->node;
- if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
- (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
- (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
- ctxt = err->ctxt;
- }
- str = err->message;
-
- if (code == XML_ERR_OK)
- return;
-
- if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
- name = node->name;
-
- /*
- * Maintain the compatibility with the legacy error handling
- */
- if (ctxt != NULL) {
- input = ctxt->input;
- if ((input != NULL) && (input->filename == NULL) &&
- (ctxt->inputNr > 1)) {
- cur = input;
- input = ctxt->inputTab[ctxt->inputNr - 2];
- }
- if (input != NULL) {
- if (input->filename)
- channel(data, "%s:%d: ", input->filename, input->line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: ", input->line);
- }
- } else {
- if (file != NULL)
- channel(data, "%s:%d: ", file, line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: ", line);
- }
- if (name != NULL) {
- channel(data, "element %s: ", name);
- }
- if (code == XML_ERR_OK)
- return;
- switch (domain) {
- case XML_FROM_PARSER:
- channel(data, "parser ");
- break;
- case XML_FROM_NAMESPACE:
- channel(data, "namespace ");
- break;
- case XML_FROM_DTD:
- case XML_FROM_VALID:
- channel(data, "validity ");
- break;
- case XML_FROM_HTML:
- channel(data, "HTML parser ");
- break;
- case XML_FROM_MEMORY:
- channel(data, "memory ");
- break;
- case XML_FROM_OUTPUT:
- channel(data, "output ");
- break;
- case XML_FROM_IO:
- channel(data, "I/O ");
- break;
- case XML_FROM_XINCLUDE:
- channel(data, "XInclude ");
- break;
- case XML_FROM_XPATH:
- channel(data, "XPath ");
- break;
- case XML_FROM_XPOINTER:
- channel(data, "parser ");
- break;
- case XML_FROM_REGEXP:
- channel(data, "regexp ");
- break;
- case XML_FROM_MODULE:
- channel(data, "module ");
- break;
- case XML_FROM_SCHEMASV:
- channel(data, "Schemas validity ");
- break;
- case XML_FROM_SCHEMASP:
- channel(data, "Schemas parser ");
- break;
- case XML_FROM_RELAXNGP:
- channel(data, "Relax-NG parser ");
- break;
- case XML_FROM_RELAXNGV:
- channel(data, "Relax-NG validity ");
- break;
- case XML_FROM_CATALOG:
- channel(data, "Catalog ");
- break;
- case XML_FROM_C14N:
- channel(data, "C14N ");
- break;
- case XML_FROM_XSLT:
- channel(data, "XSLT ");
- break;
- default:
- break;
- }
- if (code == XML_ERR_OK)
- return;
- switch (level) {
- case XML_ERR_NONE:
- channel(data, ": ");
- break;
- case XML_ERR_WARNING:
- channel(data, "warning : ");
- break;
- case XML_ERR_ERROR:
- channel(data, "error : ");
- break;
- case XML_ERR_FATAL:
- channel(data, "error : ");
- break;
- }
- if (code == XML_ERR_OK)
- return;
- if (str != NULL) {
- int len;
- len = xmlStrlen((const xmlChar *)str);
- if ((len > 0) && (str[len - 1] != '\n'))
- channel(data, "%s\n", str);
- else
- channel(data, "%s", str);
- } else {
- channel(data, "%s\n", "out of memory error");
- }
- if (code == XML_ERR_OK)
- return;
-
- if (ctxt != NULL) {
- xmlParserPrintFileContextInternal(input, channel, data);
- if (cur != NULL) {
- if (cur->filename)
- channel(data, "%s:%d: \n", cur->filename, cur->line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: \n", cur->line);
- xmlParserPrintFileContextInternal(cur, channel, data);
- }
- }
- if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
- (err->int1 < 100) &&
- (err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
- xmlChar buf[150];
- int i;
-
- channel(data, "%s\n", err->str1);
- for (i=0;i < err->int1;i++)
- buf[i] = ' ';
- buf[i++] = '^';
- buf[i] = 0;
- channel(data, "%s\n", buf);
- }
-}
-
static void
initializeLibxml2(void) {
xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
xmlInitParser();
xmlSetExternalEntityLoader(testExternalEntityLoader);
- xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
/*
* register the new I/O handlers
*/
@@ -1261,7 +993,7 @@ saxTest(const char *filename, size_t limit, int options, int fail) {
fprintf(stderr, "Failed to create parser context\n");
return(1);
}
- doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+ doc = xmlCtxtReadFile(ctxt, filename, NULL, options | XML_PARSE_NOERROR);
if (doc != NULL) {
fprintf(stderr, "SAX parsing generated a document !\n");
@@ -1308,7 +1040,7 @@ readerTest(const char *filename, size_t limit, int options, int fail) {
nb_tests++;
maxlen = limit;
- reader = xmlReaderForFile(filename , NULL, options);
+ reader = xmlReaderForFile(filename , NULL, options | XML_PARSE_NOERROR);
if (reader == NULL) {
fprintf(stderr, "Failed to open '%s' test\n", filename);
return(1);
diff --git a/testparser.c b/testparser.c
index 705e613..d19e9ea 100644
--- a/testparser.c
+++ b/testparser.c
@@ -5,8 +5,12 @@
*/
#include
+#include
+#include
#include
+#include
+
static int
testStandaloneWithEncoding(void) {
xmlDocPtr doc;
@@ -27,6 +31,80 @@ testStandaloneWithEncoding(void) {
return err;
}
+static int
+testUnsupportedEncoding(void) {
+ xmlDocPtr doc;
+ const xmlError *error;
+ int err = 0;
+
+ xmlResetLastError();
+
+ doc = xmlReadDoc(BAD_CAST "", NULL, "#unsupported",
+ XML_PARSE_NOWARNING);
+ if (doc == NULL) {
+ fprintf(stderr, "xmlReadDoc failed with unsupported encoding\n");
+ err = 1;
+ }
+ xmlFreeDoc(doc);
+
+ error = xmlGetLastError();
+ if (error->code != XML_ERR_UNSUPPORTED_ENCODING ||
+ error->level != XML_ERR_WARNING ||
+ strcmp(error->message, "Unsupported encoding: #unsupported\n") != 0)
+ {
+ fprintf(stderr, "xmlReadDoc failed to raise correct error\n");
+ err = 1;
+ }
+
+ return err;
+}
+
+static int
+testNodeGetContent(void) {
+ xmlDocPtr doc;
+ xmlChar *content;
+ int err = 0;
+
+ doc = xmlReadDoc(BAD_CAST "", NULL, NULL, 0);
+ xmlAddChild(doc->children, xmlNewReference(doc, BAD_CAST "lt"));
+ content = xmlNodeGetContent((xmlNodePtr) doc);
+ if (strcmp((char *) content, "<") != 0) {
+ fprintf(stderr, "xmlNodeGetContent failed\n");
+ err = 1;
+ }
+ xmlFree(content);
+ xmlFreeDoc(doc);
+
+ return err;
+}
+
+#ifdef LIBXML_SAX1_ENABLED
+static int
+testBalancedChunk(void) {
+ xmlNodePtr list;
+ xmlNodePtr elem;
+ int ret;
+ int err = 0;
+
+ ret = xmlParseBalancedChunkMemory(NULL, NULL, NULL, 0,
+ BAD_CAST "start abc end", &list);
+
+ if ((ret != XML_ERR_OK) ||
+ (list == NULL) ||
+ ((elem = list->next) == NULL) ||
+ (elem->type != XML_ELEMENT_NODE) ||
+ (elem->nsDef == NULL) ||
+ (!xmlStrEqual(elem->nsDef->href, XML_XML_NAMESPACE))) {
+ fprintf(stderr, "xmlParseBalancedChunkMemory failed\n");
+ err = 1;
+ }
+
+ xmlFreeNodeList(list);
+
+ return(err);
+}
+#endif
+
#ifdef LIBXML_PUSH_ENABLED
static int
testHugePush(void) {
@@ -85,9 +163,8 @@ testHugeEncodedChunk(void) {
return err;
}
-#endif
-#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_PUSH_ENABLED)
+#ifdef LIBXML_HTML_ENABLED
static int
testHtmlPushWithEncoding(void) {
htmlParserCtxtPtr ctxt;
@@ -116,19 +193,226 @@ testHtmlPushWithEncoding(void) {
return err;
}
#endif
+#endif
+
+#ifdef LIBXML_READER_ENABLED
+static int
+testReaderEncoding(void) {
+ xmlBuffer *buf;
+ xmlTextReader *reader;
+ xmlChar *xml;
+ const xmlChar *encoding;
+ int err = 0;
+ int i;
+
+ buf = xmlBufferCreate();
+ xmlBufferCCat(buf, "\n");
+ xmlBufferCCat(buf, "");
+ for (i = 0; i < 8192; i++)
+ xmlBufferCCat(buf, "x");
+ xmlBufferCCat(buf, "");
+ xml = xmlBufferDetach(buf);
+ xmlBufferFree(buf);
+
+ reader = xmlReaderForDoc(BAD_CAST xml, NULL, NULL, 0);
+ xmlTextReaderRead(reader);
+ encoding = xmlTextReaderConstEncoding(reader);
+
+ if (!xmlStrEqual(encoding, BAD_CAST "ISO-8859-1")) {
+ fprintf(stderr, "testReaderEncoding failed\n");
+ err = 1;
+ }
+
+ xmlFreeTextReader(reader);
+ xmlFree(xml);
+ return err;
+}
+
+static int
+testReaderContent(void) {
+ xmlTextReader *reader;
+ const xmlChar *xml = BAD_CAST "xyz";
+ xmlChar *string;
+ int err = 0;
+
+ reader = xmlReaderForDoc(xml, NULL, NULL, 0);
+ xmlTextReaderRead(reader);
+
+ string = xmlTextReaderReadOuterXml(reader);
+ if (!xmlStrEqual(string, xml)) {
+ fprintf(stderr, "xmlTextReaderReadOuterXml failed\n");
+ err = 1;
+ }
+ xmlFree(string);
+
+ string = xmlTextReaderReadInnerXml(reader);
+ if (!xmlStrEqual(string, BAD_CAST "xyz")) {
+ fprintf(stderr, "xmlTextReaderReadInnerXml failed\n");
+ err = 1;
+ }
+ xmlFree(string);
+
+ string = xmlTextReaderReadString(reader);
+ if (!xmlStrEqual(string, BAD_CAST "xyz")) {
+ fprintf(stderr, "xmlTextReaderReadString failed\n");
+ err = 1;
+ }
+ xmlFree(string);
+
+ xmlFreeTextReader(reader);
+ return err;
+}
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+typedef struct {
+ char *message;
+ int code;
+} testReaderErrorCtxt;
+
+static void
+testReaderError(void *arg, const char *msg,
+ xmlParserSeverities severity ATTRIBUTE_UNUSED,
+ xmlTextReaderLocatorPtr locator ATTRIBUTE_UNUSED) {
+ testReaderErrorCtxt *ctxt = arg;
+
+ if (ctxt->message != NULL)
+ xmlFree(ctxt->message);
+ ctxt->message = xmlMemStrdup(msg);
+}
+
+static void
+testStructuredReaderError(void *arg, const xmlError *error) {
+ testReaderErrorCtxt *ctxt = arg;
+
+ if (ctxt->message != NULL)
+ xmlFree(ctxt->message);
+ ctxt->message = xmlMemStrdup(error->message);
+ ctxt->code = error->code;
+}
+
+static int
+testReaderXIncludeError(void) {
+ /*
+ * Test whether XInclude errors are reported to the custom error
+ * handler of a reader.
+ */
+ const char *doc =
+ "\n"
+ " \n"
+ "\n";
+ xmlTextReader *reader;
+ testReaderErrorCtxt errorCtxt;
+ int err = 0;
+
+ reader = xmlReaderForDoc(BAD_CAST doc, NULL, NULL, XML_PARSE_XINCLUDE);
+ xmlTextReaderSetErrorHandler(reader, testReaderError, &errorCtxt);
+ errorCtxt.message = NULL;
+ errorCtxt.code = 0;
+ while (xmlTextReaderRead(reader) > 0)
+ ;
+
+ if (errorCtxt.message == NULL ||
+ strstr(errorCtxt.message, "href or xpointer") == NULL) {
+ fprintf(stderr, "xmlTextReaderSetErrorHandler failed\n");
+ err = 1;
+ }
+
+ xmlFree(errorCtxt.message);
+ xmlFreeTextReader(reader);
+
+ reader = xmlReaderForDoc(BAD_CAST doc, NULL, NULL, XML_PARSE_XINCLUDE);
+ xmlTextReaderSetStructuredErrorHandler(reader, testStructuredReaderError,
+ &errorCtxt);
+ errorCtxt.message = NULL;
+ errorCtxt.code = 0;
+ while (xmlTextReaderRead(reader) > 0)
+ ;
+
+ if (errorCtxt.code != XML_XINCLUDE_NO_HREF ||
+ errorCtxt.message == NULL ||
+ strstr(errorCtxt.message, "href or xpointer") == NULL) {
+ fprintf(stderr, "xmlTextReaderSetStructuredErrorHandler failed\n");
+ err = 1;
+ }
+
+ xmlFree(errorCtxt.message);
+ xmlFreeTextReader(reader);
+
+ return err;
+}
+#endif
+#endif
+
+#ifdef LIBXML_WRITER_ENABLED
+static int
+testWriterIOWrite(void *ctxt, const char *data, int len) {
+ (void) ctxt;
+ (void) data;
+
+ return len;
+}
+
+static int
+testWriterIOClose(void *ctxt) {
+ (void) ctxt;
+
+ return XML_IO_ENAMETOOLONG;
+}
+
+static int
+testWriterClose(void){
+ xmlOutputBufferPtr out;
+ xmlTextWriterPtr writer;
+ int err = 0;
+ int result;
+
+ out = xmlOutputBufferCreateIO(testWriterIOWrite, testWriterIOClose,
+ NULL, NULL);
+ writer = xmlNewTextWriter(out);
+ xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
+ xmlTextWriterStartElement(writer, BAD_CAST "elem");
+ xmlTextWriterEndElement(writer);
+ xmlTextWriterEndDocument(writer);
+ result = xmlTextWriterClose(writer);
+
+ if (result != XML_IO_ENAMETOOLONG) {
+ fprintf(stderr, "xmlTextWriterClose reported wrong error %d\n",
+ result);
+ err = 1;
+ }
+
+ xmlFreeTextWriter(writer);
+ return err;
+}
+#endif
int
main(void) {
int err = 0;
err |= testStandaloneWithEncoding();
+ err |= testUnsupportedEncoding();
+ err |= testNodeGetContent();
+#ifdef LIBXML_SAX1_ENABLED
+ err |= testBalancedChunk();
+#endif
#ifdef LIBXML_PUSH_ENABLED
err |= testHugePush();
err |= testHugeEncodedChunk();
-#endif
-#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_PUSH_ENABLED)
+#ifdef LIBXML_HTML_ENABLED
err |= testHtmlPushWithEncoding();
#endif
+#endif
+#ifdef LIBXML_READER_ENABLED
+ err |= testReaderEncoding();
+ err |= testReaderContent();
+#ifdef LIBXML_XINCLUDE_ENABLED
+ err |= testReaderXIncludeError();
+#endif
+#endif
+#ifdef LIBXML_WRITER_ENABLED
+ err |= testWriterClose();
+#endif
return err;
}
diff --git a/testrecurse.c b/testrecurse.c
index 5290bb2..4e69ccf 100644
--- a/testrecurse.c
+++ b/testrecurse.c
@@ -359,279 +359,11 @@ testExternalEntityLoader(const char *URL, const char *ID,
return(ret);
}
-/*
- * Trapping the error messages at the generic level to grab the equivalent of
- * stderr messages on CLI tools.
- */
-static char testErrors[32769];
-static int testErrorsSize = 0;
-
-static void
-channel(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
- va_list args;
- int res;
-
- if (testErrorsSize >= 32768)
- return;
- va_start(args, msg);
- res = vsnprintf(&testErrors[testErrorsSize],
- 32768 - testErrorsSize,
- msg, args);
- va_end(args);
- if (testErrorsSize + res >= 32768) {
- /* buffer is full */
- testErrorsSize = 32768;
- testErrors[testErrorsSize] = 0;
- } else {
- testErrorsSize += res;
- }
- testErrors[testErrorsSize] = 0;
-}
-
-/**
- * xmlParserPrintFileContext:
- * @input: an xmlParserInputPtr input
- *
- * Displays current context within the input content for error tracking
- */
-
-static void
-xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
- xmlGenericErrorFunc chanl, void *data ) {
- const xmlChar *cur, *base;
- unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */
- xmlChar content[81]; /* space for 80 chars + line terminator */
- xmlChar *ctnt;
-
- if (input == NULL) return;
- cur = input->cur;
- base = input->base;
- /* skip backwards over any end-of-lines */
- while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
- cur--;
- }
- n = 0;
- /* search backwards for beginning-of-line (to max buff size) */
- while ((n++ < (sizeof(content)-1)) && (cur > base) &&
- (*(cur) != '\n') && (*(cur) != '\r'))
- cur--;
- if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
- /* calculate the error position in terms of the current position */
- col = input->cur - cur;
- /* search forward for end-of-line (to max buff size) */
- n = 0;
- ctnt = content;
- /* copy selected text to our buffer */
- while ((*cur != 0) && (*(cur) != '\n') &&
- (*(cur) != '\r') && (n < sizeof(content)-1)) {
- *ctnt++ = *cur++;
- n++;
- }
- *ctnt = 0;
- /* print out the selected text */
- chanl(data ,"%s\n", content);
- /* create blank line with problem pointer */
- n = 0;
- ctnt = content;
- /* (leave buffer space for pointer + line terminator) */
- while ((nfile;
- line = err->line;
- code = err->code;
- domain = err->domain;
- level = err->level;
- node = err->node;
- if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
- (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
- (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
- ctxt = err->ctxt;
- }
- str = err->message;
-
- if (code == XML_ERR_OK)
- return;
-
- if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
- name = node->name;
-
- /*
- * Maintain the compatibility with the legacy error handling
- */
- if (ctxt != NULL) {
- input = ctxt->input;
- if ((input != NULL) && (input->filename == NULL) &&
- (ctxt->inputNr > 1)) {
- cur = input;
- input = ctxt->inputTab[ctxt->inputNr - 2];
- }
- if (input != NULL) {
- if (input->filename)
- channel(data, "%s:%d: ", input->filename, input->line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: ", input->line);
- }
- } else {
- if (file != NULL)
- channel(data, "%s:%d: ", file, line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: ", line);
- }
- if (name != NULL) {
- channel(data, "element %s: ", name);
- }
- if (code == XML_ERR_OK)
- return;
- switch (domain) {
- case XML_FROM_PARSER:
- channel(data, "parser ");
- break;
- case XML_FROM_NAMESPACE:
- channel(data, "namespace ");
- break;
- case XML_FROM_DTD:
- case XML_FROM_VALID:
- channel(data, "validity ");
- break;
- case XML_FROM_HTML:
- channel(data, "HTML parser ");
- break;
- case XML_FROM_MEMORY:
- channel(data, "memory ");
- break;
- case XML_FROM_OUTPUT:
- channel(data, "output ");
- break;
- case XML_FROM_IO:
- channel(data, "I/O ");
- break;
- case XML_FROM_XINCLUDE:
- channel(data, "XInclude ");
- break;
- case XML_FROM_XPATH:
- channel(data, "XPath ");
- break;
- case XML_FROM_XPOINTER:
- channel(data, "parser ");
- break;
- case XML_FROM_REGEXP:
- channel(data, "regexp ");
- break;
- case XML_FROM_MODULE:
- channel(data, "module ");
- break;
- case XML_FROM_SCHEMASV:
- channel(data, "Schemas validity ");
- break;
- case XML_FROM_SCHEMASP:
- channel(data, "Schemas parser ");
- break;
- case XML_FROM_RELAXNGP:
- channel(data, "Relax-NG parser ");
- break;
- case XML_FROM_RELAXNGV:
- channel(data, "Relax-NG validity ");
- break;
- case XML_FROM_CATALOG:
- channel(data, "Catalog ");
- break;
- case XML_FROM_C14N:
- channel(data, "C14N ");
- break;
- case XML_FROM_XSLT:
- channel(data, "XSLT ");
- break;
- default:
- break;
- }
- if (code == XML_ERR_OK)
- return;
- switch (level) {
- case XML_ERR_NONE:
- channel(data, ": ");
- break;
- case XML_ERR_WARNING:
- channel(data, "warning : ");
- break;
- case XML_ERR_ERROR:
- channel(data, "error : ");
- break;
- case XML_ERR_FATAL:
- channel(data, "error : ");
- break;
- }
- if (code == XML_ERR_OK)
- return;
- if (str != NULL) {
- int len;
- len = xmlStrlen((const xmlChar *)str);
- if ((len > 0) && (str[len - 1] != '\n'))
- channel(data, "%s\n", str);
- else
- channel(data, "%s", str);
- } else {
- channel(data, "%s\n", "out of memory error");
- }
- if (code == XML_ERR_OK)
- return;
-
- if (ctxt != NULL) {
- xmlParserPrintFileContextInternal(input, channel, data);
- if (cur != NULL) {
- if (cur->filename)
- channel(data, "%s:%d: \n", cur->filename, cur->line);
- else if ((line != 0) && (domain == XML_FROM_PARSER))
- channel(data, "Entity: line %d: \n", cur->line);
- xmlParserPrintFileContextInternal(cur, channel, data);
- }
- }
- if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
- (err->int1 < 100) &&
- (err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
- xmlChar buf[150];
- int i;
-
- channel(data, "%s\n", err->str1);
- for (i=0;i < err->int1;i++)
- buf[i] = ' ';
- buf[i++] = '^';
- buf[i] = 0;
- channel(data, "%s\n", buf);
- }
-}
-
static void
initializeLibxml2(void) {
xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
xmlInitParser();
xmlSetExternalEntityLoader(testExternalEntityLoader);
- xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
/*
* register the new I/O handlers
*/
@@ -693,10 +425,6 @@ static char *resultFilename(const char *filename, const char *out,
out = "";
strncpy(suffixbuff,suffix,499);
-#ifdef VMS
- if(strstr(base,".") && suffixbuff[0]=='.')
- suffixbuff[0]='_';
-#endif
if (snprintf(res, 499, "%s%s%s", out, base, suffixbuff) >= 499)
res[499] = 0;
@@ -761,7 +489,7 @@ recursiveDetectTest(const char *filename,
* without XML_PARSE_NOENT. The validation result doesn't matter
* anyway.
*/
- int parserOptions = XML_PARSE_DTDVALID;
+ int parserOptions = XML_PARSE_DTDVALID | XML_PARSE_NOERROR;
nb_tests++;
@@ -774,7 +502,7 @@ recursiveDetectTest(const char *filename,
* base of the test, parse with the old API
*/
doc = xmlCtxtReadFile(ctxt, filename, NULL, parserOptions);
- if ((doc != NULL) || (ctxt->lastError.code != XML_ERR_ENTITY_LOOP)) {
+ if ((doc != NULL) || (ctxt->lastError.code != XML_ERR_RESOURCE_LIMIT)) {
fprintf(stderr, "Failed to detect recursion in %s\n", filename);
xmlFreeParserCtxt(ctxt);
xmlFreeDoc(doc);
@@ -1118,8 +846,6 @@ launchTests(testDescPtr tst) {
} else {
mem = xmlMemUsed();
extraMemoryFromResolver = 0;
- testErrorsSize = 0;
- testErrors[0] = 0;
res = tst->func(globbuf.gl_pathv[i], result, error,
tst->options | XML_PARSE_COMPACT);
xmlResetLastError();
@@ -1138,7 +864,6 @@ launchTests(testDescPtr tst) {
err++;
}
}
- testErrorsSize = 0;
}
if (result)
free(result);
@@ -1147,8 +872,6 @@ launchTests(testDescPtr tst) {
}
globfree(&globbuf);
} else {
- testErrorsSize = 0;
- testErrors[0] = 0;
extraMemoryFromResolver = 0;
res = tst->func(NULL, NULL, NULL, tst->options);
if (res != 0) {
diff --git a/threads.c b/threads.c
index 461f4a5..36347c2 100644
--- a/threads.c
+++ b/threads.c
@@ -30,6 +30,7 @@
#include "private/dict.h"
#include "private/enc.h"
#include "private/globals.h"
+#include "private/io.h"
#include "private/memory.h"
#include "private/threads.h"
#include "private/xpath.h"
@@ -498,9 +499,8 @@ xmlGlobalInitMutexLock(void) {
if (global_init_lock == NULL) {
cs = malloc(sizeof(CRITICAL_SECTION));
if (cs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlGlobalInitMutexLock: out of memory\n");
- return;
+ fprintf(stderr, "libxml2: xmlInitParser: out of memory\n");
+ abort();
}
InitializeCriticalSection(cs);
@@ -583,19 +583,15 @@ xmlInitParser(void) {
atexit(xmlCleanupParser);
#endif
- xmlInitMemoryInternal(); /* Should come second */
+ xmlInitRandom(); /* Required by xmlInitGlobalsInternal */
+ xmlInitMemoryInternal();
xmlInitGlobalsInternal();
- xmlInitRandom();
xmlInitDictInternal();
xmlInitEncodingInternal();
#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
xmlInitXPathInternal();
#endif
-
- xmlRegisterDefaultInputCallbacks();
-#ifdef LIBXML_OUTPUT_ENABLED
- xmlRegisterDefaultOutputCallbacks();
-#endif /* LIBXML_OUTPUT_ENABLED */
+ xmlInitIOCallbacks();
xmlParserInnerInitialized = 1;
}
@@ -644,11 +640,6 @@ xmlCleanupParser(void) {
/* These functions should never call xmlFree. */
- xmlCleanupInputCallbacks();
-#ifdef LIBXML_OUTPUT_ENABLED
- xmlCleanupOutputCallbacks();
-#endif
-
xmlCleanupDictInternal();
xmlCleanupRandom();
xmlCleanupGlobalsInternal();
diff --git a/tree.c b/tree.c
index dc3ac4f..75f7569 100644
--- a/tree.c
+++ b/tree.c
@@ -55,58 +55,23 @@ int __xmlRegisterCallbacks = 0;
* *
************************************************************************/
+static xmlNodePtr
+xmlNewEntityRef(xmlDocPtr doc, xmlChar *name);
+
static xmlNsPtr
-xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
+xmlNewReconciledNs(xmlNodePtr tree, xmlNsPtr ns);
+
+static xmlAttrPtr
+xmlGetPropNodeInternal(const xmlNode *node, const xmlChar *name,
+ const xmlChar *nsName, int useDTD);
static xmlChar* xmlGetPropNodeValueInternal(const xmlAttr *prop);
-/************************************************************************
- * *
- * Tree memory error handler *
- * *
- ************************************************************************/
-/**
- * xmlTreeErrMemory:
- * @extra: extra information
- *
- * Handle an out of memory condition
- */
static void
-xmlTreeErrMemory(const char *extra)
-{
- __xmlSimpleError(XML_FROM_TREE, XML_ERR_NO_MEMORY, NULL, NULL, extra);
-}
+xmlBufGetChildContent(xmlBufPtr buf, const xmlNode *tree);
-/**
- * xmlTreeErr:
- * @code: the error number
- * @extra: extra information
- *
- * Handle an out of memory condition
- */
static void
-xmlTreeErr(int code, xmlNodePtr node, const char *extra)
-{
- const char *msg = NULL;
-
- switch(code) {
- case XML_TREE_INVALID_HEX:
- msg = "invalid hexadecimal character value\n";
- break;
- case XML_TREE_INVALID_DEC:
- msg = "invalid decimal character value\n";
- break;
- case XML_TREE_UNTERMINATED_ENTITY:
- msg = "unterminated entity reference %15s\n";
- break;
- case XML_TREE_NOT_UTF8:
- msg = "string is not in UTF-8\n";
- break;
- default:
- msg = "unexpected error number\n";
- }
- __xmlSimpleError(XML_FROM_TREE, code, node, msg, extra);
-}
+xmlUnlinkNodeInternal(xmlNodePtr cur);
/************************************************************************
* *
@@ -122,20 +87,6 @@ const xmlChar xmlStringTextNoenc[] =
const xmlChar xmlStringComment[] = { 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
static int xmlCompressMode = 0;
-static int xmlCheckDTD = 1;
-
-#define UPDATE_LAST_CHILD_AND_PARENT(n) if ((n) != NULL) { \
- xmlNodePtr ulccur = (n)->children; \
- if (ulccur == NULL) { \
- (n)->last = NULL; \
- } else { \
- while (ulccur->next != NULL) { \
- ulccur->parent = (n); \
- ulccur = ulccur->next; \
- } \
- ulccur->parent = (n); \
- (n)->last = ulccur; \
-}}
#define IS_STR_XML(str) ((str != NULL) && (str[0] == 'x') && \
(str[1] == 'm') && (str[2] == 'l') && (str[3] == 0))
@@ -222,15 +173,19 @@ xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix,
if (ncname == NULL) return(NULL);
if (prefix == NULL) return((xmlChar *) ncname);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ /* Make allocation more likely */
+ if (len > 8)
+ len = 8;
+#endif
+
lenn = strlen((char *) ncname);
lenp = strlen((char *) prefix);
if ((memory == NULL) || (len < lenn + lenp + 2)) {
ret = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
- if (ret == NULL) {
- xmlTreeErrMemory("building QName");
+ if (ret == NULL)
return(NULL);
- }
} else {
ret = memory;
}
@@ -246,6 +201,8 @@ xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix,
* @name: the full QName
* @prefix: a xmlChar **
*
+ * DEPRECATED: This function doesn't report malloc failures.
+ *
* parse an XML qualified name string
*
* [NS 5] QName ::= (Prefix ':')? LocalPart
@@ -267,13 +224,6 @@ xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
*prefix = NULL;
if (name == NULL) return(NULL);
-#ifndef XML_XML_NAMESPACE
- /* xml: prefix is not really a namespace */
- if ((name[0] == 'x') && (name[1] == 'm') &&
- (name[2] == 'l') && (name[3] == ':'))
- return(NULL);
-#endif
-
/* nasty but valid */
if (name[0] == ':')
return(NULL);
@@ -285,17 +235,14 @@ xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
while ((name[len] != 0) && (name[len] != ':'))
len++;
- if (name[len] == 0)
+ if ((name[len] == 0) || (name[len+1] == 0))
return(NULL);
*prefix = xmlStrndup(name, len);
- if (*prefix == NULL) {
- xmlTreeErrMemory("QName split");
+ if (*prefix == NULL)
return(NULL);
- }
ret = xmlStrdup(&name[len + 1]);
if (ret == NULL) {
- xmlTreeErrMemory("QName split");
if (*prefix != NULL) {
xmlFree(*prefix);
*prefix = NULL;
@@ -336,7 +283,7 @@ xmlSplitQName3(const xmlChar *name, int *len) {
while ((name[l] != 0) && (name[l] != ':'))
l++;
- if (name[l] == 0)
+ if ((name[l] == 0) || (name[l+1] == 0))
return(NULL);
*len = l;
@@ -344,6 +291,53 @@ xmlSplitQName3(const xmlChar *name, int *len) {
return(&name[l+1]);
}
+/**
+ * xmlSplitQName4:
+ * @name: the full QName
+ * @prefixPtr: pointer to resulting prefix
+ *
+ * Parse a QName. The return value points to the start of the local
+ * name in the input string. If the QName has a prefix, it will be
+ * allocated and stored in @prefixPtr. This string must be freed by
+ * the caller. If there's no prefix, @prefixPtr is set to NULL.
+ *
+ * Returns the local name or NULL if a memory allocation failed.
+ */
+const xmlChar *
+xmlSplitQName4(const xmlChar *name, xmlChar **prefixPtr) {
+ xmlChar *prefix;
+ int l = 0;
+
+ if ((name == NULL) || (prefixPtr == NULL))
+ return(NULL);
+
+ *prefixPtr = NULL;
+
+ /* nasty but valid */
+ if (name[0] == ':')
+ return(name);
+
+ /*
+ * we are not trying to validate but just to cut, and yes it will
+ * work even if this is as set of UTF-8 encoded chars
+ */
+ while ((name[l] != 0) && (name[l] != ':'))
+ l++;
+
+ /*
+ * TODO: What about names with multiple colons?
+ */
+ if ((name[l] == 0) || (name[l+1] == 0))
+ return(name);
+
+ prefix = xmlStrndup(name, l);
+ if (prefix == NULL)
+ return(NULL);
+
+ *prefixPtr = prefix;
+ return(&name[l+1]);
+}
+
/************************************************************************
* *
* Check Name, NCName and QName strings *
@@ -708,19 +702,21 @@ xmlGetBufferAllocationScheme(void) {
/**
* xmlNewNs:
- * @node: the element carrying the namespace
+ * @node: the element carrying the namespace (optional)
* @href: the URI associated
- * @prefix: the prefix for the namespace
+ * @prefix: the prefix for the namespace (optional)
*
- * Creation of a new Namespace. This function will refuse to create
- * a namespace with a similar prefix than an existing one present on this
- * node.
- * Note that for a default namespace, @prefix should be NULL.
+ * Create a new namespace. For a default namespace, @prefix should be
+ * NULL. The namespace URI in @href is not checked. You should make sure
+ * to pass a valid URI.
*
- * We use href==NULL in the case of an element creation where the namespace
- * was not defined.
+ * If @node is provided, it must be an element node. The namespace will
+ * be appended to the node's namespace declarations. It is an error if
+ * the node already has a definition for the prefix or default
+ * namespace.
*
- * Returns a new namespace pointer or NULL
+ * Returns a new namespace pointer or NULL if arguments are invalid,
+ * the prefix is already in use or a memory allocation failed.
*/
xmlNsPtr
xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
@@ -729,35 +725,25 @@ xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
return(NULL);
- if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
- /* xml namespace is predefined, no need to add it */
- if (xmlStrEqual(href, XML_XML_NAMESPACE))
- return(NULL);
-
- /*
- * Problem, this is an attempt to bind xml prefix to a wrong
- * namespace, which breaks
- * Namespace constraint: Reserved Prefixes and Namespace Names
- * from XML namespace. But documents authors may not care in
- * their context so let's proceed.
- */
- }
-
/*
* Allocate a new Namespace and fill the fields.
*/
cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (cur == NULL) {
- xmlTreeErrMemory("building namespace");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlNs));
cur->type = XML_LOCAL_NAMESPACE;
- if (href != NULL)
+ if (href != NULL) {
cur->href = xmlStrdup(href);
- if (prefix != NULL)
+ if (cur->href == NULL)
+ goto error;
+ }
+ if (prefix != NULL) {
cur->prefix = xmlStrdup(prefix);
+ if (cur->prefix == NULL)
+ goto error;
+ }
/*
* Add it at the end to preserve parsing order ...
@@ -769,31 +755,32 @@ xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
} else {
xmlNsPtr prev = node->nsDef;
- if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
- (xmlStrEqual(prev->prefix, cur->prefix))) {
- xmlFreeNs(cur);
- return(NULL);
- }
+ if ((xmlStrEqual(prev->prefix, cur->prefix)) &&
+ (prev->href != NULL))
+ goto error;
while (prev->next != NULL) {
prev = prev->next;
- if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
- (xmlStrEqual(prev->prefix, cur->prefix))) {
- xmlFreeNs(cur);
- return(NULL);
- }
+ if ((xmlStrEqual(prev->prefix, cur->prefix)) &&
+ (prev->href != NULL))
+ goto error;
}
prev->next = cur;
}
}
return(cur);
+
+error:
+ xmlFreeNs(cur);
+ return(NULL);
}
/**
* xmlSetNs:
* @node: a node in the document
- * @ns: a namespace pointer
+ * @ns: a namespace pointer (optional)
*
- * Associate a namespace to a node, a posteriori.
+ * Set the namespace of an element or attribute node. Passing a NULL
+ * namespace unsets the namespace.
*/
void
xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
@@ -809,7 +796,7 @@ xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
* xmlFreeNs:
* @cur: the namespace pointer
*
- * Free up the structures associated to a namespace
+ * Free an xmlNs object.
*/
void
xmlFreeNs(xmlNsPtr cur) {
@@ -825,7 +812,7 @@ xmlFreeNs(xmlNsPtr cur) {
* xmlFreeNsList:
* @cur: the first namespace pointer
*
- * Free up all the structures associated to the chained namespaces.
+ * Free a list of xmlNs objects.
*/
void
xmlFreeNsList(xmlNsPtr cur) {
@@ -842,15 +829,21 @@ xmlFreeNsList(xmlNsPtr cur) {
/**
* xmlNewDtd:
- * @doc: the document pointer
- * @name: the DTD name
- * @ExternalID: the external ID
- * @SystemID: the system ID
+ * @doc: the document pointer (optional)
+ * @name: the DTD name (optional)
+ * @ExternalID: the external ID (optional)
+ * @SystemID: the system ID (optional)
+ *
+ * Create a DTD node.
*
- * Creation of a new DTD for the external subset. To create an
- * internal subset, use xmlCreateIntSubset().
+ * If a document is provided, it is an error if it already has an
+ * external subset. If the document has no external subset, it
+ * will be set to the created DTD.
*
- * Returns a pointer to the new DTD structure
+ * To create an internal subset, use xmlCreateIntSubset().
+ *
+ * Returns a pointer to the new DTD object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
xmlDtdPtr
xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
@@ -865,19 +858,26 @@ xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
* Allocate a new DTD and fill the fields.
*/
cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
- if (cur == NULL) {
- xmlTreeErrMemory("building DTD");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0 , sizeof(xmlDtd));
cur->type = XML_DTD_NODE;
- if (name != NULL)
+ if (name != NULL) {
cur->name = xmlStrdup(name);
- if (ExternalID != NULL)
+ if (cur->name == NULL)
+ goto error;
+ }
+ if (ExternalID != NULL) {
cur->ExternalID = xmlStrdup(ExternalID);
- if (SystemID != NULL)
+ if (cur->ExternalID == NULL)
+ goto error;
+ }
+ if (SystemID != NULL) {
cur->SystemID = xmlStrdup(SystemID);
+ if (cur->SystemID == NULL)
+ goto error;
+ }
if (doc != NULL)
doc->extSubset = cur;
cur->doc = doc;
@@ -885,16 +885,20 @@ xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
+
+error:
+ xmlFreeDtd(cur);
+ return(NULL);
}
/**
* xmlGetIntSubset:
* @doc: the document pointer
*
- * Get the internal subset of a document
- * Returns a pointer to the DTD structure or NULL if not found
+ * Get the internal subset of a document.
+ *
+ * Returns a pointer to the DTD object or NULL if not found.
*/
-
xmlDtdPtr
xmlGetIntSubset(const xmlDoc *doc) {
xmlNodePtr cur;
@@ -912,63 +916,55 @@ xmlGetIntSubset(const xmlDoc *doc) {
/**
* xmlCreateIntSubset:
- * @doc: the document pointer
- * @name: the DTD name
- * @ExternalID: the external (PUBLIC) ID
- * @SystemID: the system ID
+ * @doc: the document pointer (optional)
+ * @name: the DTD name (optional)
+ * @ExternalID: the external (PUBLIC) ID (optional)
+ * @SystemID: the system ID (optional)
*
- * Create the internal subset of a document
- * Returns a pointer to the new DTD structure
+ * Create a DTD node.
+ *
+ * If a document is provided and it already has an internal subset,
+ * the existing DTD object is returned without creating a new object.
+ * If the document has no internal subset, it will be set to the
+ * created DTD.
+ *
+ * Returns a pointer to the new or existing DTD object or NULL if
+ * arguments are invalid or a memory allocation failed.
*/
xmlDtdPtr
xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
const xmlChar *ExternalID, const xmlChar *SystemID) {
xmlDtdPtr cur;
- if ((doc != NULL) && (xmlGetIntSubset(doc) != NULL)) {
- return(NULL);
+ if (doc != NULL) {
+ cur = xmlGetIntSubset(doc);
+ if (cur != NULL)
+ return(cur);
}
/*
* Allocate a new DTD and fill the fields.
*/
cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
- if (cur == NULL) {
- xmlTreeErrMemory("building internal subset");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlDtd));
cur->type = XML_DTD_NODE;
if (name != NULL) {
cur->name = xmlStrdup(name);
- if (cur->name == NULL) {
- xmlTreeErrMemory("building internal subset");
- xmlFree(cur);
- return(NULL);
- }
+ if (cur->name == NULL)
+ goto error;
}
if (ExternalID != NULL) {
cur->ExternalID = xmlStrdup(ExternalID);
- if (cur->ExternalID == NULL) {
- xmlTreeErrMemory("building internal subset");
- if (cur->name != NULL)
- xmlFree((char *)cur->name);
- xmlFree(cur);
- return(NULL);
- }
+ if (cur->ExternalID == NULL)
+ goto error;
}
if (SystemID != NULL) {
cur->SystemID = xmlStrdup(SystemID);
- if (cur->SystemID == NULL) {
- xmlTreeErrMemory("building internal subset");
- if (cur->name != NULL)
- xmlFree((char *)cur->name);
- if (cur->ExternalID != NULL)
- xmlFree((char *)cur->ExternalID);
- xmlFree(cur);
- return(NULL);
- }
+ if (cur->SystemID == NULL)
+ goto error;
}
if (doc != NULL) {
doc->intSubset = cur;
@@ -1012,6 +1008,10 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
+
+error:
+ xmlFreeDtd(cur);
+ return(NULL);
}
/**
@@ -1026,42 +1026,6 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str));
-
-/**
- * DICT_COPY:
- * @str: a string
- *
- * Copy a string using a "dict" dictionary in the current scope,
- * if available.
- */
-#define DICT_COPY(str, cpy) \
- if (str) { \
- if (dict) { \
- if (xmlDictOwns(dict, (const xmlChar *)(str))) \
- cpy = (xmlChar *) (str); \
- else \
- cpy = (xmlChar *) xmlDictLookup((dict), (const xmlChar *)(str), -1); \
- } else \
- cpy = xmlStrdup((const xmlChar *)(str)); }
-
-/**
- * DICT_CONST_COPY:
- * @str: a string
- *
- * Copy a string using a "dict" dictionary in the current scope,
- * if available.
- */
-#define DICT_CONST_COPY(str, cpy) \
- if (str) { \
- if (dict) { \
- if (xmlDictOwns(dict, (const xmlChar *)(str))) \
- cpy = (const xmlChar *) (str); \
- else \
- cpy = xmlDictLookup((dict), (const xmlChar *)(str), -1); \
- } else \
- cpy = (const xmlChar *) xmlStrdup((const xmlChar *)(str)); }
-
-
/**
* xmlFreeDtd:
* @cur: the DTD structure to free up
@@ -1089,11 +1053,10 @@ xmlFreeDtd(xmlDtdPtr cur) {
*/
while (c != NULL) {
next = c->next;
- if ((c->type != XML_NOTATION_NODE) &&
- (c->type != XML_ELEMENT_DECL) &&
+ if ((c->type != XML_ELEMENT_DECL) &&
(c->type != XML_ATTRIBUTE_DECL) &&
(c->type != XML_ENTITY_DECL)) {
- xmlUnlinkNode(c);
+ xmlUnlinkNodeInternal(c);
xmlFreeNode(c);
}
c = next;
@@ -1120,11 +1083,11 @@ xmlFreeDtd(xmlDtdPtr cur) {
/**
* xmlNewDoc:
- * @version: xmlChar string giving the version of XML "1.0"
+ * @version: XML version string like "1.0" (optional)
*
- * Creates a new XML document
+ * Creates a new XML document. If version is NULL, "1.0" is used.
*
- * Returns a new document
+ * Returns a new document or NULL if a memory allocation failed.
*/
xmlDocPtr
xmlNewDoc(const xmlChar *version) {
@@ -1137,16 +1100,13 @@ xmlNewDoc(const xmlChar *version) {
* Allocate a new document and fill the fields.
*/
cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
- if (cur == NULL) {
- xmlTreeErrMemory("building doc");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlDoc));
cur->type = XML_DOCUMENT_NODE;
cur->version = xmlStrdup(version);
if (cur->version == NULL) {
- xmlTreeErrMemory("building doc");
xmlFree(cur);
return(NULL);
}
@@ -1171,7 +1131,7 @@ xmlNewDoc(const xmlChar *version) {
* xmlFreeDoc:
* @cur: pointer to the document
*
- * Free up all the structures used by a document, tree included.
+ * Free a document including all children and associated DTDs.
*/
void
xmlFreeDoc(xmlDocPtr cur) {
@@ -1182,7 +1142,7 @@ xmlFreeDoc(xmlDocPtr cur) {
return;
}
- if (cur != NULL) dict = cur->dict;
+ dict = cur->dict;
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
@@ -1199,12 +1159,12 @@ xmlFreeDoc(xmlDocPtr cur) {
if (intSubset == extSubset)
extSubset = NULL;
if (extSubset != NULL) {
- xmlUnlinkNode((xmlNodePtr) cur->extSubset);
+ xmlUnlinkNodeInternal((xmlNodePtr) cur->extSubset);
cur->extSubset = NULL;
xmlFreeDtd(extSubset);
}
if (intSubset != NULL) {
- xmlUnlinkNode((xmlNodePtr) cur->intSubset);
+ xmlUnlinkNodeInternal((xmlNodePtr) cur->intSubset);
cur->intSubset = NULL;
xmlFreeDtd(intSubset);
}
@@ -1221,38 +1181,52 @@ xmlFreeDoc(xmlDocPtr cur) {
}
/**
- * xmlStringLenGetNodeList:
- * @doc: the document
- * @value: the value of the text
- * @len: the length of the string value
+ * xmlNodeParseContentInternal:
+ * @doc: a document (optional)
+ * @parent: an element or attribute (optional)
+ * @value: an attribute value
+ * @len: maximum length of the attribute value
+ * @listPtr: pointer to the resulting node list (optional)
+ *
+ * See xmlNodeParseContent.
*
- * Parse the value string and build the node list associated. Should
- * produce a flat tree with only TEXTs and ENTITY_REFs.
- * Returns a pointer to the first child
+ * Returns 0 on success, -1 if a memory allocation failed.
*/
-xmlNodePtr
-xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
- xmlNodePtr ret = NULL, last = NULL;
+static int
+xmlNodeParseContentInternal(const xmlDoc *doc, xmlNodePtr parent,
+ const xmlChar *value, int len,
+ xmlNodePtr *listPtr) {
+ xmlNodePtr head = NULL, last = NULL;
xmlNodePtr node;
- xmlChar *val;
- const xmlChar *cur, *end;
+ xmlChar *val = NULL;
+ const xmlChar *cur;
const xmlChar *q;
xmlEntityPtr ent;
xmlBufPtr buf;
+ int remaining;
+
+ if (listPtr != NULL)
+ *listPtr = NULL;
+
+ if (len < 0)
+ remaining = INT_MAX;
+ else
+ remaining = len;
+
+ if (value == NULL)
+ goto done;
- if (value == NULL) return(NULL);
cur = value;
- end = cur + len;
- buf = xmlBufCreateSize(0);
- if (buf == NULL) return(NULL);
+ buf = xmlBufCreateSize(64);
+ if (buf == NULL)
+ return(-1);
xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
q = cur;
- while ((cur < end) && (*cur != 0)) {
+ while ((remaining > 0) && (*cur != 0)) {
if (cur[0] == '&') {
int charval = 0;
- xmlChar tmp;
/*
* Save the current text.
@@ -1260,25 +1234,15 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
if (cur != q) {
if (xmlBufAdd(buf, q, cur - q))
goto out;
+ q = cur;
}
- q = cur;
- if ((cur + 2 < end) && (cur[1] == '#') && (cur[2] == 'x')) {
+
+ if ((remaining > 2) && (cur[1] == '#') && (cur[2] == 'x')) {
+ int tmp = 0;
+
cur += 3;
- if (cur < end)
- tmp = *cur;
- else
- tmp = 0;
- while (tmp != ';') { /* Non input consuming loop */
- /*
- * If you find an integer overflow here when fuzzing,
- * the bug is probably elsewhere. This function should
- * only receive entities that were already validated by
- * the parser, typically by xmlParseAttValueComplex
- * calling xmlStringDecodeEntities.
- *
- * So it's better *not* to check for overflow to
- * potentially discover new bugs.
- */
+ remaining -= 3;
+ while ((remaining > 0) && ((tmp = *cur) != ';')) {
if ((tmp >= '0') && (tmp <= '9'))
charval = charval * 16 + (tmp - '0');
else if ((tmp >= 'a') && (tmp <= 'f'))
@@ -1286,142 +1250,147 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
else if ((tmp >= 'A') && (tmp <= 'F'))
charval = charval * 16 + (tmp - 'A') + 10;
else {
- xmlTreeErr(XML_TREE_INVALID_HEX, (xmlNodePtr) doc,
- NULL);
charval = 0;
break;
}
+ if (charval > 0x110000)
+ charval = 0x110000;
cur++;
- if (cur < end)
- tmp = *cur;
- else
- tmp = 0;
+ remaining--;
}
- if (tmp == ';')
+ if (tmp == ';') {
cur++;
+ remaining--;
+ }
q = cur;
- } else if ((cur + 1 < end) && (cur[1] == '#')) {
+ } else if ((remaining > 1) && (cur[1] == '#')) {
+ int tmp = 0;
+
cur += 2;
- if (cur < end)
- tmp = *cur;
- else
- tmp = 0;
- while (tmp != ';') { /* Non input consuming loops */
- /* Don't check for integer overflow, see above. */
+ remaining -= 2;
+ while ((remaining > 0) && ((tmp = *cur) != ';')) {
if ((tmp >= '0') && (tmp <= '9'))
charval = charval * 10 + (tmp - '0');
else {
- xmlTreeErr(XML_TREE_INVALID_DEC, (xmlNodePtr) doc,
- NULL);
charval = 0;
break;
}
+ if (charval > 0x110000)
+ charval = 0x110000;
cur++;
- if (cur < end)
- tmp = *cur;
- else
- tmp = 0;
+ remaining--;
}
- if (tmp == ';')
+ if (tmp == ';') {
cur++;
+ remaining--;
+ }
q = cur;
} else {
/*
* Read the entity string
*/
cur++;
+ remaining--;
q = cur;
- while ((cur < end) && (*cur != 0) && (*cur != ';')) cur++;
- if ((cur >= end) || (*cur == 0)) {
- xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, (xmlNodePtr) doc,
- (const char *) q);
- goto out;
- }
+ while ((remaining > 0) && (*cur != 0) && (*cur != ';')) {
+ cur++;
+ remaining--;
+ }
+ if ((remaining <= 0) || (*cur == 0))
+ break;
if (cur != q) {
- /*
- * Predefined entities don't generate nodes
- */
val = xmlStrndup(q, cur - q);
+ if (val == NULL)
+ goto out;
ent = xmlGetDocEntity(doc, val);
if ((ent != NULL) &&
(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
-
+ /*
+ * Predefined entities don't generate nodes
+ */
if (xmlBufCat(buf, ent->content))
goto out;
-
} else {
/*
* Flush buffer so far
*/
if (!xmlBufIsEmpty(buf)) {
node = xmlNewDocText(doc, NULL);
- if (node == NULL) {
- if (val != NULL) xmlFree(val);
+ if (node == NULL)
goto out;
- }
node->content = xmlBufDetach(buf);
+ node->parent = parent;
if (last == NULL) {
- last = ret = node;
+ head = node;
} else {
- last = xmlAddNextSibling(last, node);
+ last->next = node;
+ node->prev = last;
}
+ last = node;
+ }
+
+ if ((ent != NULL) &&
+ ((ent->flags & XML_ENT_PARSED) == 0) &&
+ ((ent->flags & XML_ENT_EXPANDING) == 0) &&
+ (ent->content != NULL)) {
+ int res;
+
+ ent->flags |= XML_ENT_EXPANDING;
+ res = xmlNodeParseContentInternal(doc,
+ (xmlNodePtr) ent, ent->content, -1, NULL);
+ ent->flags &= ~XML_ENT_EXPANDING;
+ if (res < 0)
+ goto out;
+ ent->flags |= XML_ENT_PARSED;
}
/*
* Create a new REFERENCE_REF node
*/
- node = xmlNewReference(doc, val);
- if (node == NULL) {
- if (val != NULL) xmlFree(val);
+ node = xmlNewEntityRef((xmlDocPtr) doc, val);
+ val = NULL;
+ if (node == NULL)
goto out;
- }
- else if ((ent != NULL) &&
- ((ent->flags & XML_ENT_PARSED) == 0) &&
- ((ent->flags & XML_ENT_EXPANDING) == 0)) {
- xmlNodePtr temp;
-
- /*
- * The entity should have been checked already,
- * but set the flag anyway to avoid recursion.
- */
- ent->flags |= XML_ENT_EXPANDING;
- ent->children = xmlStringGetNodeList(doc,
- (const xmlChar*)node->content);
- ent->owner = 1;
- ent->flags &= ~XML_ENT_EXPANDING;
- ent->flags |= XML_ENT_PARSED;
- temp = ent->children;
- while (temp) {
- temp->parent = (xmlNodePtr)ent;
- ent->last = temp;
- temp = temp->next;
- }
- }
+ node->parent = parent;
+ node->last = (xmlNodePtr) ent;
+ if (ent != NULL) {
+ node->children = (xmlNodePtr) ent;
+ node->content = ent->content;
+ }
+
if (last == NULL) {
- last = ret = node;
+ head = node;
} else {
- last = xmlAddNextSibling(last, node);
+ last->next = node;
+ node->prev = last;
}
+ last = node;
}
xmlFree(val);
+ val = NULL;
}
cur++;
+ remaining--;
q = cur;
}
if (charval != 0) {
xmlChar buffer[10];
int l;
+ if (charval >= 0x110000)
+ charval = 0xFFFD; /* replacement character */
+
l = xmlCopyCharMultiByte(buffer, charval);
buffer[l] = 0;
if (xmlBufCat(buf, buffer))
goto out;
- charval = 0;
}
- } else
+ } else {
cur++;
+ remaining--;
+ }
}
if (cur != q) {
@@ -1434,398 +1403,250 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
if (!xmlBufIsEmpty(buf)) {
node = xmlNewDocText(doc, NULL);
- if (node == NULL) goto out;
+ if (node == NULL)
+ goto out;
+ node->parent = parent;
node->content = xmlBufDetach(buf);
if (last == NULL) {
- ret = node;
+ head = node;
} else {
- xmlAddNextSibling(last, node);
+ last->next = node;
+ node->prev = last;
}
- } else if (ret == NULL) {
- ret = xmlNewDocText(doc, BAD_CAST "");
+ last = node;
+ } else if (head == NULL) {
+ head = xmlNewDocText(doc, BAD_CAST "");
+ if (head == NULL)
+ goto out;
+ head->parent = parent;
+ last = head;
}
+ xmlBufFree(buf);
+
+done:
+ if (parent != NULL) {
+ if (parent->children != NULL)
+ xmlFreeNodeList(parent->children);
+ parent->children = head;
+ parent->last = last;
+ }
+
+ if (listPtr != NULL)
+ *listPtr = head;
+
+ return(0);
+
out:
xmlBufFree(buf);
+ if (val != NULL)
+ xmlFree(val);
+ if (head != NULL)
+ xmlFreeNodeList(head);
+ return(-1);
+}
+
+/**
+ * xmlNodeParseContent:
+ * @node: an element or attribute
+ * @content: text content with XML references
+ * @len: maximum length of content
+ *
+ * Parse content and replace the node's children with the resulting
+ * node list.
+ *
+ * @content is expected to be a valid XML attribute value possibly
+ * containing character and entity references. Syntax errors
+ * and references to undeclared entities are ignored silently.
+ * Only references are handled, nested elements, comments or PIs are
+ * not.
+ *
+ * Returns 0 on success, -1 if a memory allocation failed.
+ */
+int
+xmlNodeParseContent(xmlNodePtr node, const xmlChar *content, int len) {
+ return(xmlNodeParseContentInternal(node->doc, node, content, len, NULL));
+}
+
+/**
+ * xmlStringLenGetNodeList:
+ * @doc: a document (optional)
+ * @value: an attribute value
+ * @len: maximum length of the attribute value
+ *
+ * DEPRECATED: Use xmlNodeSetContentLen.
+ *
+ * See xmlStringGetNodeList.
+ *
+ * Returns a pointer to the first child or NULL if a memory
+ * allocation failed.
+ */
+xmlNodePtr
+xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
+ xmlNodePtr ret;
+
+ xmlNodeParseContentInternal(doc, NULL, value, len, &ret);
return(ret);
}
/**
* xmlStringGetNodeList:
- * @doc: the document
- * @value: the value of the attribute
+ * @doc: a document (optional)
+ * @value: an attribute value
+ *
+ * DEPRECATED: Use xmlNodeSetContent.
+ *
+ * Parse an attribute value and build a node list containing only
+ * text and entity reference nodes. The resulting nodes will be
+ * associated with the document if provided. The document is also
+ * used to look up entities.
*
- * Parse the value string and build the node list associated. Should
- * produce a flat tree with only TEXTs and ENTITY_REFs.
- * Returns a pointer to the first child
+ * The input is not validated. Syntax errors or references to
+ * undeclared entities will be ignored silently with unspecified
+ * results.
+ *
+ * Returns a pointer to the first child or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr
xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
- xmlNodePtr ret = NULL, head = NULL, last = NULL;
- xmlNodePtr node;
- xmlChar *val = NULL;
- const xmlChar *cur = value;
- const xmlChar *q;
- xmlEntityPtr ent;
+ xmlNodePtr ret;
+
+ xmlNodeParseContentInternal(doc, NULL, value, -1, &ret);
+ return(ret);
+}
+
+/**
+ * xmlNodeListGetStringInternal:
+ * @doc: a document (optional)
+ * @node: a node list
+ * @escMode: escape mode (0 = no, 1 = elem, 2 = attr, 3 = raw)
+ *
+ * Returns a pointer to the string.
+ */
+static xmlChar *
+xmlNodeListGetStringInternal(xmlDocPtr doc, const xmlNode *node, int escMode) {
xmlBufPtr buf;
+ xmlChar *ret;
- if (value == NULL) return(NULL);
+ if (node == NULL)
+ return(xmlStrdup(BAD_CAST ""));
- buf = xmlBufCreateSize(0);
- if (buf == NULL) return(NULL);
- xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
+ if ((escMode == 0) &&
+ ((node->type == XML_TEXT_NODE) ||
+ (node->type == XML_CDATA_SECTION_NODE)) &&
+ (node->next == NULL)) {
+ if (node->content == NULL)
+ return(xmlStrdup(BAD_CAST ""));
+ return(xmlStrdup(node->content));
+ }
- q = cur;
- while (*cur != 0) {
- if (cur[0] == '&') {
- int charval = 0;
- xmlChar tmp;
+ buf = xmlBufCreateSize(64);
+ if (buf == NULL)
+ return(NULL);
- /*
- * Save the current text.
- */
- if (cur != q) {
- if (xmlBufAdd(buf, q, cur - q))
- goto out;
- }
- q = cur;
- if ((cur[1] == '#') && (cur[2] == 'x')) {
- cur += 3;
- tmp = *cur;
- while (tmp != ';') { /* Non input consuming loop */
- /* Don't check for integer overflow, see above. */
- if ((tmp >= '0') && (tmp <= '9'))
- charval = charval * 16 + (tmp - '0');
- else if ((tmp >= 'a') && (tmp <= 'f'))
- charval = charval * 16 + (tmp - 'a') + 10;
- else if ((tmp >= 'A') && (tmp <= 'F'))
- charval = charval * 16 + (tmp - 'A') + 10;
- else {
- xmlTreeErr(XML_TREE_INVALID_HEX, (xmlNodePtr) doc,
- NULL);
- charval = 0;
- break;
- }
- cur++;
- tmp = *cur;
- }
- if (tmp == ';')
- cur++;
- q = cur;
- } else if (cur[1] == '#') {
- cur += 2;
- tmp = *cur;
- while (tmp != ';') { /* Non input consuming loops */
- /* Don't check for integer overflow, see above. */
- if ((tmp >= '0') && (tmp <= '9'))
- charval = charval * 10 + (tmp - '0');
- else {
- xmlTreeErr(XML_TREE_INVALID_DEC, (xmlNodePtr) doc,
- NULL);
- charval = 0;
- break;
- }
- cur++;
- tmp = *cur;
- }
- if (tmp == ';')
- cur++;
- q = cur;
- } else {
- /*
- * Read the entity string
- */
- cur++;
- q = cur;
- while ((*cur != 0) && (*cur != ';')) cur++;
- if (*cur == 0) {
- xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY,
- (xmlNodePtr) doc, (const char *) q);
- goto out;
- }
- if (cur != q) {
- /*
- * Predefined entities don't generate nodes
- */
- val = xmlStrndup(q, cur - q);
- ent = xmlGetDocEntity(doc, val);
- if ((ent != NULL) &&
- (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
-
- if (xmlBufCat(buf, ent->content))
- goto out;
-
- } else {
- /*
- * Flush buffer so far
- */
- if (!xmlBufIsEmpty(buf)) {
- node = xmlNewDocText(doc, NULL);
- if (node == NULL)
- goto out;
- node->content = xmlBufDetach(buf);
-
- if (last == NULL) {
- last = head = node;
- } else {
- last = xmlAddNextSibling(last, node);
- }
- }
-
- /*
- * Create a new REFERENCE_REF node
- */
- node = xmlNewReference(doc, val);
- if (node == NULL)
- goto out;
- if ((ent != NULL) &&
- ((ent->flags & XML_ENT_PARSED) == 0) &&
- ((ent->flags & XML_ENT_EXPANDING) == 0)) {
- xmlNodePtr temp;
-
- /*
- * The entity should have been checked already,
- * but set the flag anyway to avoid recursion.
- */
- ent->flags |= XML_ENT_EXPANDING;
- ent->children = xmlStringGetNodeList(doc,
- (const xmlChar*)node->content);
- ent->owner = 1;
- ent->flags &= ~XML_ENT_EXPANDING;
- ent->flags |= XML_ENT_PARSED;
- temp = ent->children;
- while (temp) {
- temp->parent = (xmlNodePtr)ent;
- ent->last = temp;
- temp = temp->next;
- }
- }
- if (last == NULL) {
- last = head = node;
- } else {
- last = xmlAddNextSibling(last, node);
- }
- }
- xmlFree(val);
- val = NULL;
- }
- cur++;
- q = cur;
- }
- if (charval != 0) {
- xmlChar buffer[10];
- int len;
-
- len = xmlCopyCharMultiByte(buffer, charval);
- buffer[len] = 0;
-
- if (xmlBufCat(buf, buffer))
- goto out;
- charval = 0;
- }
- } else
- cur++;
- }
- if ((cur != q) || (head == NULL)) {
- /*
- * Handle the last piece of text.
- */
- xmlBufAdd(buf, q, cur - q);
- }
-
- if (!xmlBufIsEmpty(buf)) {
- node = xmlNewDocText(doc, NULL);
- if (node == NULL)
- goto out;
- node->content = xmlBufDetach(buf);
+ while (node != NULL) {
+ if ((node->type == XML_TEXT_NODE) ||
+ (node->type == XML_CDATA_SECTION_NODE)) {
+ if (node->content != NULL) {
+ if (escMode == 0) {
+ xmlBufCat(buf, node->content);
+ } else {
+ xmlChar *encoded;
+
+ if (escMode == 1)
+ encoded = xmlEncodeEntitiesReentrant(doc,
+ node->content);
+ else if (escMode == 2)
+ encoded = xmlEncodeAttributeEntities(doc,
+ node->content);
+ else
+ encoded = xmlEncodeSpecialChars(doc, node->content);
+ if (encoded == NULL)
+ goto error;
+ xmlBufCat(buf, encoded);
+ xmlFree(encoded);
+ }
+ }
+ } else if (node->type == XML_ENTITY_REF_NODE) {
+ if (escMode == 0) {
+ xmlBufGetNodeContent(buf, node);
+ } else {
+ xmlBufAdd(buf, BAD_CAST "&", 1);
+ xmlBufCat(buf, node->name);
+ xmlBufAdd(buf, BAD_CAST ";", 1);
+ }
+ }
- if (last == NULL) {
- head = node;
- } else {
- xmlAddNextSibling(last, node);
- }
+ node = node->next;
}
- ret = head;
- head = NULL;
-
-out:
+ ret = xmlBufDetach(buf);
xmlBufFree(buf);
- if (val != NULL) xmlFree(val);
- if (head != NULL) xmlFreeNodeList(head);
return(ret);
+
+error:
+ xmlBufFree(buf);
+ return(NULL);
}
/**
* xmlNodeListGetString:
- * @doc: the document
- * @list: a Node list
- * @inLine: should we replace entity contents or show their external form
+ * @doc: a document (optional)
+ * @list: a node list of attribute children (optional)
+ * @inLine: whether entity references are substituted
*
- * Build the string equivalent to the text contained in the Node list
- * made of TEXTs and ENTITY_REFs
+ * Serializes attribute children (text and entity reference nodes)
+ * into a string. An empty list produces an empty string.
*
- * Returns a pointer to the string copy, the caller must free it with xmlFree().
+ * If @inLine is true, entity references will be substituted.
+ * Otherwise, entity references will be kept and special characters
+ * like '&' as well as non-ASCII chars will be escaped. See
+ * xmlNodeListGetRawString for an alternative option.
+ *
+ * Returns a string or NULL if a memory allocation failed.
*/
xmlChar *
xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
{
- const xmlNode *node = list;
- xmlChar *ret = NULL;
- xmlEntityPtr ent;
- int attr;
-
- if (list == NULL)
- return (NULL);
- if ((list->parent != NULL) && (list->parent->type == XML_ATTRIBUTE_NODE))
- attr = 1;
- else
- attr = 0;
-
- while (node != NULL) {
- if ((node->type == XML_TEXT_NODE) ||
- (node->type == XML_CDATA_SECTION_NODE)) {
- if (inLine) {
- ret = xmlStrcat(ret, node->content);
- } else {
- xmlChar *buffer;
+ int escMode;
- if (attr)
- buffer = xmlEncodeAttributeEntities(doc, node->content);
- else
- buffer = xmlEncodeEntitiesReentrant(doc, node->content);
- if (buffer != NULL) {
- ret = xmlStrcat(ret, buffer);
- xmlFree(buffer);
- }
- }
- } else if (node->type == XML_ENTITY_REF_NODE) {
- if (inLine) {
- ent = xmlGetDocEntity(doc, node->name);
- if (ent != NULL) {
- xmlChar *buffer;
-
- /* an entity content can be any "well balanced chunk",
- * i.e. the result of the content [43] production:
- * http://www.w3.org/TR/REC-xml#NT-content.
- * So it can contain text, CDATA section or nested
- * entity reference nodes (among others).
- * -> we recursive call xmlNodeListGetString()
- * which handles these types */
- buffer = xmlNodeListGetString(doc, ent->children, 1);
- if (buffer != NULL) {
- ret = xmlStrcat(ret, buffer);
- xmlFree(buffer);
- }
- } else {
- ret = xmlStrcat(ret, node->content);
- }
- } else {
- xmlChar buf[2];
-
- buf[0] = '&';
- buf[1] = 0;
- ret = xmlStrncat(ret, buf, 1);
- ret = xmlStrcat(ret, node->name);
- buf[0] = ';';
- buf[1] = 0;
- ret = xmlStrncat(ret, buf, 1);
- }
- }
-#if 0
- else {
- xmlGenericError(xmlGenericErrorContext,
- "xmlGetNodeListString : invalid node type %d\n",
- node->type);
- }
-#endif
- node = node->next;
+ if (inLine) {
+ escMode = 0;
+ } else {
+ if ((list != NULL) &&
+ (list->parent != NULL) &&
+ (list->parent->type == XML_ATTRIBUTE_NODE))
+ escMode = 2;
+ else
+ escMode = 1;
}
- return (ret);
+
+ return(xmlNodeListGetStringInternal(doc, list, escMode));
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlNodeListGetRawString:
- * @doc: the document
- * @list: a Node list
- * @inLine: should we replace entity contents or show their external form
+ * @doc: a document (optional)
+ * @list: a node list of attribute children (optional)
+ * @inLine: whether entity references are substituted
+ *
+ * Serializes attribute children (text and entity reference nodes)
+ * into a string. An empty list produces an empty string.
*
- * Builds the string equivalent to the text contained in the Node list
- * made of TEXTs and ENTITY_REFs, contrary to xmlNodeListGetString()
- * this function doesn't do any character encoding handling.
+ * If @inLine is true, entity references will be substituted.
+ * Otherwise, entity references will be kept and special characters
+ * like '&' will be escaped.
*
- * Returns a pointer to the string copy, the caller must free it with xmlFree().
+ * Returns a string or NULL if a memory allocation failed.
*/
xmlChar *
xmlNodeListGetRawString(const xmlDoc *doc, const xmlNode *list, int inLine)
{
- const xmlNode *node = list;
- xmlChar *ret = NULL;
- xmlEntityPtr ent;
-
- if (list == NULL)
- return (NULL);
-
- while (node != NULL) {
- if ((node->type == XML_TEXT_NODE) ||
- (node->type == XML_CDATA_SECTION_NODE)) {
- if (inLine) {
- ret = xmlStrcat(ret, node->content);
- } else {
- xmlChar *buffer;
-
- buffer = xmlEncodeSpecialChars(doc, node->content);
- if (buffer != NULL) {
- ret = xmlStrcat(ret, buffer);
- xmlFree(buffer);
- }
- }
- } else if (node->type == XML_ENTITY_REF_NODE) {
- if (inLine) {
- ent = xmlGetDocEntity(doc, node->name);
- if (ent != NULL) {
- xmlChar *buffer;
-
- /* an entity content can be any "well balanced chunk",
- * i.e. the result of the content [43] production:
- * http://www.w3.org/TR/REC-xml#NT-content.
- * So it can contain text, CDATA section or nested
- * entity reference nodes (among others).
- * -> we recursive call xmlNodeListGetRawString()
- * which handles these types */
- buffer =
- xmlNodeListGetRawString(doc, ent->children, 1);
- if (buffer != NULL) {
- ret = xmlStrcat(ret, buffer);
- xmlFree(buffer);
- }
- } else {
- ret = xmlStrcat(ret, node->content);
- }
- } else {
- xmlChar buf[2];
-
- buf[0] = '&';
- buf[1] = 0;
- ret = xmlStrncat(ret, buf, 1);
- ret = xmlStrcat(ret, node->name);
- buf[0] = ';';
- buf[1] = 0;
- ret = xmlStrncat(ret, buf, 1);
- }
- }
-#if 0
- else {
- xmlGenericError(xmlGenericErrorContext,
- "xmlGetNodeListString : invalid node type %d\n",
- node->type);
- }
-#endif
- node = node->next;
- }
- return (ret);
+ int escMode = inLine ? 0 : 3;
+ return(xmlNodeListGetStringInternal((xmlDocPtr) doc, list, escMode));
}
#endif /* LIBXML_TREE_ENABLED */
@@ -1855,7 +1676,6 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
(node->doc->dict == NULL) ||
(!(xmlDictOwns(node->doc->dict, name)))))
xmlFree((xmlChar *) name);
- xmlTreeErrMemory("building attribute");
return (NULL);
}
memset(cur, 0, sizeof(xmlAttr));
@@ -1873,6 +1693,8 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
cur->name = (xmlChar *) xmlDictLookup(doc->dict, name, -1);
else
cur->name = xmlStrdup(name);
+ if (cur->name == NULL)
+ goto error;
} else
cur->name = name;
@@ -1880,6 +1702,8 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
xmlNodePtr tmp;
cur->children = xmlNewDocText(doc, value);
+ if (cur->children == NULL)
+ goto error;
cur->last = NULL;
tmp = cur->children;
while (tmp != NULL) {
@@ -1888,6 +1712,15 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
cur->last = tmp;
tmp = tmp->next;
}
+
+ if (doc != NULL) {
+ int res = xmlIsID(doc, node, cur);
+
+ if (res < 0)
+ goto error;
+ if ((res == 1) && (xmlAddIDSafe(cur, value) < 0))
+ goto error;
+ }
}
/*
@@ -1906,25 +1739,33 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
}
}
- if ((value != NULL) && (node != NULL) &&
- (xmlIsID(node->doc, node, cur) == 1))
- xmlAddID(NULL, node->doc, value, cur);
-
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr) cur);
return (cur);
+
+error:
+ xmlFreeProp(cur);
+ return(NULL);
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
defined(LIBXML_SCHEMAS_ENABLED)
/**
* xmlNewProp:
- * @node: the holding node
+ * @node: the parent node (optional)
* @name: the name of the attribute
- * @value: the value of the attribute
+ * @value: the value of the attribute (optional)
+ *
+ * Create an attribute node.
+ *
+ * If provided, @value should be a raw, unescaped string.
+ *
+ * If @node is provided, the created attribute will be appended without
+ * checking for duplicate names. It is an error if @node is not an
+ * element.
*
- * Create a new property carried by a node.
- * Returns a pointer to the attribute
+ * Returns a pointer to the attribute or NULL if arguments are invalid
+ * or a memory allocation failed.
*/
xmlAttrPtr
xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
@@ -1939,13 +1780,21 @@ xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
/**
* xmlNewNsProp:
- * @node: the holding node
- * @ns: the namespace
- * @name: the name of the attribute
- * @value: the value of the attribute
+ * @node: the parent node (optional)
+ * @ns: the namespace (optional)
+ * @name: the local name of the attribute
+ * @value: the value of the attribute (optional)
+ *
+ * Create an attribute object.
+ *
+ * If provided, @value should be a raw, unescaped string.
+ *
+ * If @node is provided, the created attribute will be appended without
+ * checking for duplicate names. It is an error if @node is not an
+ * element.
*
- * Create a new property tagged with a namespace and carried by a node.
- * Returns a pointer to the attribute
+ * Returns a pointer to the attribute or NULL if arguments are invalid
+ * or a memory allocation failed.
*/
xmlAttrPtr
xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
@@ -1960,13 +1809,17 @@ xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
/**
* xmlNewNsPropEatName:
- * @node: the holding node
- * @ns: the namespace
- * @name: the name of the attribute
- * @value: the value of the attribute
+ * @node: the parent node (optional)
+ * @ns: the namespace (optional)
+ * @name: the local name of the attribute
+ * @value: the value of the attribute (optional)
+ *
+ * Like xmlNewNsProp, but the @name string will be used directly
+ * without making a copy. Takes ownership of @name which will also
+ * be freed on error.
*
- * Create a new property tagged with a namespace and carried by a node.
- * Returns a pointer to the attribute
+ * Returns a pointer to the attribute or NULL if arguments are invalid
+ * or a memory allocation failed.
*/
xmlAttrPtr
xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name,
@@ -1981,17 +1834,19 @@ xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name,
/**
* xmlNewDocProp:
- * @doc: the document
+ * @doc: the target document (optional)
* @name: the name of the attribute
- * @value: the value of the attribute
+ * @value: attribute value with XML references (optional)
+ *
+ * Create an attribute object.
*
- * Create a new property carried by a document.
- * NOTE: @value is supposed to be a piece of XML CDATA, so it allows entity
- * references, but XML special chars need to be escaped first by using
- * xmlEncodeEntitiesReentrant(). Use xmlNewProp() if you don't need
- * entities support.
+ * If provided, @value is expected to be a valid XML attribute value
+ * possibly containing character and entity references. Syntax errors
+ * and references to undeclared entities are ignored silently.
+ * If you want to pass a raw string, see xmlNewProp.
*
- * Returns a pointer to the attribute
+ * Returns a pointer to the attribute or NULL if arguments are invalid
+ * or a memory allocation failed.
*/
xmlAttrPtr
xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) {
@@ -2005,10 +1860,8 @@ xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) {
* Allocate a new property and fill the fields.
*/
cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
- if (cur == NULL) {
- xmlTreeErrMemory("building attribute");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlAttr));
cur->type = XML_ATTRIBUTE_NODE;
@@ -2016,32 +1869,28 @@ xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) {
cur->name = xmlDictLookup(doc->dict, name, -1);
else
cur->name = xmlStrdup(name);
+ if (cur->name == NULL)
+ goto error;
cur->doc = doc;
if (value != NULL) {
- xmlNodePtr tmp;
-
- cur->children = xmlStringGetNodeList(doc, value);
- cur->last = NULL;
-
- tmp = cur->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) cur;
- if (tmp->next == NULL)
- cur->last = tmp;
- tmp = tmp->next;
- }
+ if (xmlNodeParseContent((xmlNodePtr) cur, value, -1) < 0)
+ goto error;
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
+
+error:
+ xmlFreeProp(cur);
+ return(NULL);
}
/**
* xmlFreePropList:
- * @cur: the first property in the list
+ * @cur: the first attribute in the list
*
- * Free a property and all its siblings, all the children are freed too.
+ * Free an attribute list including all children.
*/
void
xmlFreePropList(xmlAttrPtr cur) {
@@ -2058,7 +1907,7 @@ xmlFreePropList(xmlAttrPtr cur) {
* xmlFreeProp:
* @cur: an attribute
*
- * Free one attribute, all the content is freed too
+ * Free an attribute including all children.
*/
void
xmlFreeProp(xmlAttrPtr cur) {
@@ -2083,10 +1932,14 @@ xmlFreeProp(xmlAttrPtr cur) {
* xmlRemoveProp:
* @cur: an attribute
*
- * Unlink and free one attribute, all the content is freed too
- * Note this doesn't work for namespace definition attributes
+ * Unlink and free an attribute including all children.
+ *
+ * Note this doesn't work for namespace declarations.
*
- * Returns 0 if success and -1 in case of error.
+ * The attribute must have a non-NULL parent pointer.
+ *
+ * Returns 0 on success or -1 if the attribute was not found or
+ * arguments are invalid.
*/
int
xmlRemoveProp(xmlAttrPtr cur) {
@@ -2120,12 +1973,14 @@ xmlRemoveProp(xmlAttrPtr cur) {
/**
* xmlNewDocPI:
- * @doc: the target document
- * @name: the processing instruction name
- * @content: the PI content
+ * @doc: the target document (optional)
+ * @name: the processing instruction target
+ * @content: the PI content (optional)
*
- * Creation of a processing instruction element.
- * Returns a pointer to the new node object.
+ * Create a processing instruction object.
+ *
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewDocPI(xmlDocPtr doc, const xmlChar *name, const xmlChar *content) {
@@ -2139,37 +1994,44 @@ xmlNewDocPI(xmlDocPtr doc, const xmlChar *name, const xmlChar *content) {
* Allocate a new node and fill the fields.
*/
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlTreeErrMemory("building PI");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlNode));
cur->type = XML_PI_NODE;
+ cur->doc = doc;
if ((doc != NULL) && (doc->dict != NULL))
cur->name = xmlDictLookup(doc->dict, name, -1);
else
cur->name = xmlStrdup(name);
+ if (cur->name == NULL)
+ goto error;
if (content != NULL) {
cur->content = xmlStrdup(content);
+ if (cur->content == NULL)
+ goto error;
}
- cur->doc = doc;
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
+
+error:
+ xmlFreeNode(cur);
+ return(NULL);
}
/**
* xmlNewPI:
- * @name: the processing instruction name
- * @content: the PI content
+ * @name: the processing instruction target
+ * @content: the PI content (optional)
*
- * Creation of a processing instruction element.
+ * Create a processing instruction node.
*
* Use of this function is DISCOURAGED in favor of xmlNewDocPI.
*
- * Returns a pointer to the new node object.
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewPI(const xmlChar *name, const xmlChar *content) {
@@ -2178,116 +2040,122 @@ xmlNewPI(const xmlChar *name, const xmlChar *content) {
/**
* xmlNewNode:
- * @ns: namespace if any
+ * @ns: namespace (optional)
* @name: the node name
*
- * Creation of a new node element. @ns is optional (NULL).
+ * Create an element node.
*
* Use of this function is DISCOURAGED in favor of xmlNewDocNode.
*
- * Returns a pointer to the new node object. Uses xmlStrdup() to make
- * copy of @name.
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewNode(xmlNsPtr ns, const xmlChar *name) {
- xmlNodePtr cur;
-
- if (name == NULL) {
- return(NULL);
- }
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlTreeErrMemory("building node");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_ELEMENT_NODE;
-
- cur->name = xmlStrdup(name);
- cur->ns = ns;
-
- if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
- xmlRegisterNodeDefaultValue(cur);
- return(cur);
+ return(xmlNewDocNode(NULL, ns, name, NULL));
}
/**
* xmlNewNodeEatName:
- * @ns: namespace if any
+ * @ns: namespace (optional)
* @name: the node name
*
- * Creation of a new node element. @ns is optional (NULL).
+ * Create an element node.
*
* Use of this function is DISCOURAGED in favor of xmlNewDocNodeEatName.
*
- * Returns a pointer to the new node object, with pointer @name as
- * new node's name. Use xmlNewNode() if a copy of @name string is
- * is needed as new node's name.
+ * Like xmlNewNode, but the @name string will be used directly
+ * without making a copy. Takes ownership of @name which will also
+ * be freed on error.
+ *
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewNodeEatName(xmlNsPtr ns, xmlChar *name) {
- xmlNodePtr cur;
+ return(xmlNewDocNodeEatName(NULL, ns, name, NULL));
+}
- if (name == NULL) {
- return(NULL);
- }
+static xmlNodePtr
+xmlNewElem(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name,
+ const xmlChar *content) {
+ xmlNodePtr cur;
- /*
- * Allocate a new node and fill the fields.
- */
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlTreeErrMemory("building node");
- /* we can't check here that name comes from the doc dictionary */
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_ELEMENT_NODE;
+ cur->type = XML_ELEMENT_NODE;
+ cur->doc = doc;
cur->name = name;
cur->ns = ns;
+ if (content != NULL) {
+ if (xmlNodeParseContent(cur, content, -1) < 0) {
+ /* Don't free name on error */
+ xmlFree(cur);
+ return(NULL);
+ }
+ }
+
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
+
return(cur);
}
/**
* xmlNewDocNode:
- * @doc: the document
- * @ns: namespace if any
+ * @doc: the target document
+ * @ns: namespace (optional)
* @name: the node name
- * @content: the XML text content if any
+ * @content: text content with XML references (optional)
+ *
+ * Create an element node.
*
- * Creation of a new node element within a document. @ns and @content
- * are optional (NULL).
- * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
- * references, but XML special chars need to be escaped first by using
- * xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
- * need entities support.
+ * If provided, @content is expected to be a valid XML attribute value
+ * possibly containing character and entity references. Syntax errors
+ * and references to undeclared entities are ignored silently.
+ * Only references are handled, nested elements, comments or PIs are
+ * not. See xmlNewDocRawNode for an alternative.
*
- * Returns a pointer to the new node object.
+ * General notes on object creation:
+ *
+ * Each node and all its children are associated with the same
+ * document. The document should be provided when creating nodes to
+ * avoid a performance penalty when adding the node to a document
+ * tree. Note that a document only owns nodes reachable from the root
+ * node. Unlinked subtrees must be freed manually.
+ *
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
const xmlChar *name, const xmlChar *content) {
xmlNodePtr cur;
+ xmlChar *copy;
- if ((doc != NULL) && (doc->dict != NULL))
- cur = xmlNewNodeEatName(ns, (xmlChar *)
- xmlDictLookup(doc->dict, name, -1));
- else
- cur = xmlNewNode(ns, name);
- if (cur != NULL) {
- cur->doc = doc;
- if (content != NULL) {
- cur->children = xmlStringGetNodeList(doc, content);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
- }
+ if (name == NULL)
+ return(NULL);
+
+ if ((doc != NULL) && (doc->dict != NULL)) {
+ const xmlChar *dictName = xmlDictLookup(doc->dict, name, -1);
+
+ if (dictName == NULL)
+ return(NULL);
+ return(xmlNewElem(doc, ns, dictName, content));
+ }
+
+ copy = xmlStrdup(name);
+ if (copy == NULL)
+ return(NULL);
+
+ cur = xmlNewElem(doc, ns, copy, content);
+ if (cur == NULL) {
+ xmlFree(copy);
+ return(NULL);
}
return(cur);
@@ -2295,54 +2163,55 @@ xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
/**
* xmlNewDocNodeEatName:
- * @doc: the document
- * @ns: namespace if any
+ * @doc: the target document
+ * @ns: namespace (optional)
* @name: the node name
- * @content: the XML text content if any
+ * @content: text content with XML references (optional)
+ *
+ * Create an element node.
*
- * Creation of a new node element within a document. @ns and @content
- * are optional (NULL).
- * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
- * references, but XML special chars need to be escaped first by using
- * xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
- * need entities support.
+ * Like xmlNewDocNode, but the @name string will be used directly
+ * without making a copy. Takes ownership of @name which will also
+ * be freed on error.
*
- * Returns a pointer to the new node object.
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewDocNodeEatName(xmlDocPtr doc, xmlNsPtr ns,
- xmlChar *name, const xmlChar *content) {
+ xmlChar *name, const xmlChar *content) {
xmlNodePtr cur;
- cur = xmlNewNodeEatName(ns, name);
- if (cur != NULL) {
- cur->doc = doc;
- if (content != NULL) {
- cur->children = xmlStringGetNodeList(doc, content);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
- }
- } else {
- /* if name don't come from the doc dictionary free it here */
- if ((name != NULL) &&
- ((doc == NULL) || (doc->dict == NULL) ||
- (!(xmlDictOwns(doc->dict, name)))))
- xmlFree(name);
+ if (name == NULL)
+ return(NULL);
+
+ cur = xmlNewElem(doc, ns, name, content);
+ if (cur == NULL) {
+ /* if name doesn't come from the doc dictionary free it here */
+ if ((doc == NULL) ||
+ (doc->dict == NULL) ||
+ (!xmlDictOwns(doc->dict, name)))
+ xmlFree(name);
+ return(NULL);
}
+
return(cur);
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlNewDocRawNode:
- * @doc: the document
- * @ns: namespace if any
+ * @doc: the target document
+ * @ns: namespace (optional)
* @name: the node name
- * @content: the text content if any
+ * @content: raw text content (optional)
+ *
+ * Create an element node.
*
- * Creation of a new node element within a document. @ns and @content
- * are optional (NULL).
+ * If provided, @value should be a raw, unescaped string.
*
- * Returns a pointer to the new node object.
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewDocRawNode(xmlDocPtr doc, xmlNsPtr ns,
@@ -2353,8 +2222,17 @@ xmlNewDocRawNode(xmlDocPtr doc, xmlNsPtr ns,
if (cur != NULL) {
cur->doc = doc;
if (content != NULL) {
- cur->children = xmlNewDocText(doc, content);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
+ xmlNodePtr text;
+
+ text = xmlNewDocText(doc, content);
+ if (text == NULL) {
+ xmlFreeNode(cur);
+ return(NULL);
+ }
+
+ cur->children = text;
+ cur->last = text;
+ text->parent = cur;
}
}
return(cur);
@@ -2362,10 +2240,12 @@ xmlNewDocRawNode(xmlDocPtr doc, xmlNsPtr ns,
/**
* xmlNewDocFragment:
- * @doc: the document owning the fragment
+ * @doc: the target document (optional)
*
- * Creation of a new Fragment node.
- * Returns a pointer to the new node object.
+ * Create a document fragment node.
+ *
+ * Returns a pointer to the new node object or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr
xmlNewDocFragment(xmlDocPtr doc) {
@@ -2375,10 +2255,8 @@ xmlNewDocFragment(xmlDocPtr doc) {
* Allocate a new DocumentFragment node and fill the fields.
*/
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlTreeErrMemory("building fragment");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlNode));
cur->type = XML_DOCUMENT_FRAG_NODE;
@@ -2392,13 +2270,14 @@ xmlNewDocFragment(xmlDocPtr doc) {
/**
* xmlNewText:
- * @content: the text content
+ * @content: raw text content (optional)
*
- * Creation of a new text node.
+ * Create a text node.
*
* Use of this function is DISCOURAGED in favor of xmlNewDocText.
*
- * Returns a pointer to the new node object.
+ * Returns a pointer to the new node object or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr
xmlNewText(const xmlChar *content) {
@@ -2408,83 +2287,77 @@ xmlNewText(const xmlChar *content) {
* Allocate a new node and fill the fields.
*/
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlTreeErrMemory("building text");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlNode));
cur->type = XML_TEXT_NODE;
cur->name = xmlStringText;
if (content != NULL) {
cur->content = xmlStrdup(content);
+ if (cur->content == NULL)
+ goto error;
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue(cur);
return(cur);
+
+error:
+ xmlFreeNode(cur);
+ return(NULL);
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlNewTextChild:
* @parent: the parent node
- * @ns: a namespace if any
+ * @ns: a namespace (optional)
* @name: the name of the child
- * @content: the text content of the child if any.
+ * @content: raw text content of the child (optional)
+ *
+ * Create a new child element and append it to a parent element.
+ *
+ * If @ns is NULL, the newly created element inherits the namespace
+ * of the parent.
*
- * Creation of a new child element, added at the end of @parent children list.
- * @ns and @content parameters are optional (NULL). If @ns is NULL, the newly
- * created element inherits the namespace of @parent. If @content is non NULL,
- * a child TEXT node will be created containing the string @content.
- * NOTE: Use xmlNewChild() if @content will contain entities that need to be
- * preserved. Use this function, xmlNewTextChild(), if you need to ensure that
- * reserved XML chars that might appear in @content, such as the ampersand,
- * greater-than or less-than signs, are automatically replaced by their XML
- * escaped entity representations.
+ * If @content is provided, a text node will be added to the child
+ * element, see xmlNewDocRawNode.
*
- * Returns a pointer to the new node object.
+ * Returns a pointer to the new node object or NULL if arguments
+ * are invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewTextChild(xmlNodePtr parent, xmlNsPtr ns,
const xmlChar *name, const xmlChar *content) {
xmlNodePtr cur, prev;
- if (parent == NULL) {
+ if ((parent == NULL) || (name == NULL))
return(NULL);
- }
- if (name == NULL) {
- return(NULL);
- }
+ switch (parent->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_DOCUMENT_FRAG_NODE:
+ break;
- /*
- * Allocate a new node
- */
- if (parent->type == XML_ELEMENT_NODE) {
- if (ns == NULL)
- cur = xmlNewDocRawNode(parent->doc, parent->ns, name, content);
- else
- cur = xmlNewDocRawNode(parent->doc, ns, name, content);
- } else if ((parent->type == XML_DOCUMENT_NODE) ||
- (parent->type == XML_HTML_DOCUMENT_NODE)) {
- if (ns == NULL)
- cur = xmlNewDocRawNode((xmlDocPtr) parent, NULL, name, content);
- else
- cur = xmlNewDocRawNode((xmlDocPtr) parent, ns, name, content);
- } else if (parent->type == XML_DOCUMENT_FRAG_NODE) {
- cur = xmlNewDocRawNode( parent->doc, ns, name, content);
- } else {
- return(NULL);
+ case XML_ELEMENT_NODE:
+ if (ns == NULL)
+ ns = parent->ns;
+ break;
+
+ default:
+ return(NULL);
}
- if (cur == NULL) return(NULL);
+
+ cur = xmlNewDocRawNode(parent->doc, ns, name, content);
+ if (cur == NULL)
+ return(NULL);
/*
* add the new element at the end of the children list.
*/
- cur->type = XML_ELEMENT_NODE;
cur->parent = parent;
- cur->doc = parent->doc;
if (parent->children == NULL) {
parent->children = cur;
parent->last = cur;
@@ -2500,55 +2373,92 @@ xmlNewTextChild(xmlNodePtr parent, xmlNsPtr ns,
#endif /* LIBXML_TREE_ENABLED */
/**
- * xmlNewCharRef:
- * @doc: the document
- * @name: the char ref string, starting with # or " ... ;"
+ * xmlNewEntityRef:
+ * @doc: the target document (optional)
+ * @name: the entity name
*
- * Creation of a new character reference node.
- * Returns a pointer to the new node object.
+ * Create an empty entity reference node. This function doesn't attempt
+ * to look up the entity in @doc.
+ *
+ * @name is consumed.
+ *
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
-xmlNodePtr
-xmlNewCharRef(xmlDocPtr doc, const xmlChar *name) {
+static xmlNodePtr
+xmlNewEntityRef(xmlDocPtr doc, xmlChar *name) {
xmlNodePtr cur;
- if (name == NULL)
- return(NULL);
-
/*
* Allocate a new node and fill the fields.
*/
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
if (cur == NULL) {
- xmlTreeErrMemory("building character reference");
+ xmlFree(name);
return(NULL);
}
memset(cur, 0, sizeof(xmlNode));
cur->type = XML_ENTITY_REF_NODE;
-
cur->doc = doc;
+ cur->name = name;
+
+ if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+ xmlRegisterNodeDefaultValue(cur);
+
+ return(cur);
+}
+
+/**
+ * xmlNewCharRef:
+ * @doc: the target document (optional)
+ * @name: the entity name
+ *
+ * This function is MISNAMED. It doesn't create a character reference
+ * but an entity reference.
+ *
+ * Create an empty entity reference node. This function doesn't attempt
+ * to look up the entity in @doc.
+ *
+ * Entity names like '&entity;' are handled as well.
+ *
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
+ */
+xmlNodePtr
+xmlNewCharRef(xmlDocPtr doc, const xmlChar *name) {
+ xmlChar *copy;
+
+ if (name == NULL)
+ return(NULL);
+
if (name[0] == '&') {
int len;
name++;
len = xmlStrlen(name);
if (name[len - 1] == ';')
- cur->name = xmlStrndup(name, len - 1);
+ copy = xmlStrndup(name, len - 1);
else
- cur->name = xmlStrndup(name, len);
+ copy = xmlStrndup(name, len);
} else
- cur->name = xmlStrdup(name);
+ copy = xmlStrdup(name);
+ if (copy == NULL)
+ return(NULL);
- if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
- xmlRegisterNodeDefaultValue(cur);
- return(cur);
+ return(xmlNewEntityRef(doc, copy));
}
/**
* xmlNewReference:
- * @doc: the document
- * @name: the reference name, or the reference string with & and ;
+ * @doc: the target document (optional)
+ * @name: the entity name
+ *
+ * Create a new entity reference node, linking the result with the
+ * entity in @doc if found.
*
- * Creation of a new reference node.
- * Returns a pointer to the new node object.
+ * Entity names like '&entity;' are handled as well.
+ *
+ * Returns a pointer to the new node object or NULL if arguments are
+ * invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewReference(const xmlDoc *doc, const xmlChar *name) {
@@ -2562,10 +2472,8 @@ xmlNewReference(const xmlDoc *doc, const xmlChar *name) {
* Allocate a new node and fill the fields.
*/
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlTreeErrMemory("building reference");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlNode));
cur->type = XML_ENTITY_REF_NODE;
@@ -2580,6 +2488,8 @@ xmlNewReference(const xmlDoc *doc, const xmlChar *name) {
cur->name = xmlStrndup(name, len);
} else
cur->name = xmlStrdup(name);
+ if (cur->name == NULL)
+ goto error;
ent = xmlGetDocEntity(doc, cur->name);
if (ent != NULL) {
@@ -2596,15 +2506,21 @@ xmlNewReference(const xmlDoc *doc, const xmlChar *name) {
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue(cur);
return(cur);
+
+error:
+ xmlFreeNode(cur);
+ return(NULL);
}
/**
* xmlNewDocText:
- * @doc: the document
- * @content: the text content
+ * @doc: the target document
+ * @content: raw text content (optional)
*
- * Creation of a new text node within a document.
- * Returns a pointer to the new node object.
+ * Create a new text node.
+ *
+ * Returns a pointer to the new node object or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr
xmlNewDocText(const xmlDoc *doc, const xmlChar *content) {
@@ -2617,13 +2533,13 @@ xmlNewDocText(const xmlDoc *doc, const xmlChar *content) {
/**
* xmlNewTextLen:
- * @content: the text content
- * @len: the text len.
+ * @content: raw text content (optional)
+ * @len: size of text content
*
* Use of this function is DISCOURAGED in favor of xmlNewDocTextLen.
*
- * Creation of a new text node with an extra parameter for the content's length
- * Returns a pointer to the new node object.
+ * Returns a pointer to the new node object or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr
xmlNewTextLen(const xmlChar *content, int len) {
@@ -2633,16 +2549,18 @@ xmlNewTextLen(const xmlChar *content, int len) {
* Allocate a new node and fill the fields.
*/
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlTreeErrMemory("building text");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlNode));
cur->type = XML_TEXT_NODE;
cur->name = xmlStringText;
if (content != NULL) {
cur->content = xmlStrndup(content, len);
+ if (cur->content == NULL) {
+ xmlFreeNode(cur);
+ return(NULL);
+ }
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
@@ -2652,13 +2570,14 @@ xmlNewTextLen(const xmlChar *content, int len) {
/**
* xmlNewDocTextLen:
- * @doc: the document
- * @content: the text content
- * @len: the text len.
+ * @doc: the target document
+ * @content: raw text content (optional)
+ * @len: size of text content
+ *
+ * Create a new text node.
*
- * Creation of a new text node with an extra content length parameter. The
- * text node pertain to a given document.
- * Returns a pointer to the new node object.
+ * Returns a pointer to the new node object or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr
xmlNewDocTextLen(xmlDocPtr doc, const xmlChar *content, int len) {
@@ -2671,12 +2590,14 @@ xmlNewDocTextLen(xmlDocPtr doc, const xmlChar *content, int len) {
/**
* xmlNewComment:
- * @content: the comment content
+ * @content: the comment content (optional)
*
* Use of this function is DISCOURAGED in favor of xmlNewDocComment.
*
- * Creation of a new node containing a comment.
- * Returns a pointer to the new node object.
+ * Create a comment node.
+ *
+ * Returns a pointer to the new node object or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr
xmlNewComment(const xmlChar *content) {
@@ -2686,31 +2607,37 @@ xmlNewComment(const xmlChar *content) {
* Allocate a new node and fill the fields.
*/
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlTreeErrMemory("building comment");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlNode));
cur->type = XML_COMMENT_NODE;
cur->name = xmlStringComment;
if (content != NULL) {
cur->content = xmlStrdup(content);
+ if (cur->content == NULL)
+ goto error;
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue(cur);
return(cur);
+
+error:
+ xmlFreeNode(cur);
+ return(NULL);
}
/**
* xmlNewCDataBlock:
- * @doc: the document
- * @content: the CDATA block content content
- * @len: the length of the block
+ * @doc: the target document (optional)
+ * @content: raw text content (optional)
+ * @len: size of text content
+ *
+ * Create a CDATA section node.
*
- * Creation of a new node containing a CDATA block.
- * Returns a pointer to the new node object.
+ * Returns a pointer to the new node object or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr
xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
@@ -2720,16 +2647,18 @@ xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
* Allocate a new node and fill the fields.
*/
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlTreeErrMemory("building CDATA");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlNode));
cur->type = XML_CDATA_SECTION_NODE;
cur->doc = doc;
if (content != NULL) {
cur->content = xmlStrndup(content, len);
+ if (cur->content == NULL) {
+ xmlFree(cur);
+ return(NULL);
+ }
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
@@ -2742,8 +2671,10 @@ xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
* @doc: the document
* @content: the comment content
*
- * Creation of a new node containing a comment within a document.
- * Returns a pointer to the new node object.
+ * Create a comment node.
+ *
+ * Returns a pointer to the new node object or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr
xmlNewDocComment(xmlDocPtr doc, const xmlChar *content) {
@@ -2754,164 +2685,293 @@ xmlNewDocComment(xmlDocPtr doc, const xmlChar *content) {
return(cur);
}
-static const xmlChar *_copyStringForNewDictIfNeeded(xmlDictPtr oldDict, xmlDictPtr newDict, const xmlChar *oldValue) {
- const xmlChar *newValue = oldValue;
- if (oldValue) {
- int oldDictOwnsOldValue = oldDict && (xmlDictOwns(oldDict, oldValue) == 1);
- if (oldDictOwnsOldValue) {
+static void
+xmlRemoveEntity(xmlEntityPtr ent) {
+ xmlDocPtr doc = ent->doc;
+ xmlDtdPtr intSubset, extSubset;
+
+ if (doc == NULL)
+ return;
+ intSubset = doc->intSubset;
+ extSubset = doc->extSubset;
+
+ if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
+ (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
+ (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY)) {
+ if (intSubset != NULL) {
+ if (xmlHashLookup(intSubset->entities, ent->name) == ent)
+ xmlHashRemoveEntry(intSubset->entities, ent->name, NULL);
+ }
+ if (extSubset != NULL) {
+ if (xmlHashLookup(extSubset->entities, ent->name) == ent)
+ xmlHashRemoveEntry(extSubset->entities, ent->name, NULL);
+ }
+ } else if ((ent->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
+ (ent->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
+ if (intSubset != NULL) {
+ if (xmlHashLookup(intSubset->pentities, ent->name) == ent)
+ xmlHashRemoveEntry(intSubset->entities, ent->name, NULL);
+ }
+ if (extSubset != NULL) {
+ if (xmlHashLookup(extSubset->pentities, ent->name) == ent)
+ xmlHashRemoveEntry(extSubset->entities, ent->name, NULL);
+ }
+ }
+}
+
+static int
+xmlNodeSetDoc(xmlNodePtr node, xmlDocPtr doc) {
+ xmlDocPtr oldDoc;
+ xmlDictPtr oldDict, newDict;
+ int ret = 0;
+
+ /*
+ * Remove name and content from old dictionary
+ */
+
+ oldDoc = node->doc;
+ oldDict = oldDoc ? oldDoc->dict : NULL;
+ newDict = doc ? doc->dict : NULL;
+
+ if ((oldDict != NULL) && (oldDict != newDict)) {
+ if ((node->name != NULL) &&
+ ((node->type == XML_ELEMENT_NODE) ||
+ (node->type == XML_ATTRIBUTE_NODE) ||
+ (node->type == XML_PI_NODE) ||
+ (node->type == XML_ENTITY_REF_NODE)) &&
+ (xmlDictOwns(oldDict, node->name))) {
if (newDict)
- newValue = xmlDictLookup(newDict, oldValue, -1);
+ node->name = xmlDictLookup(newDict, node->name, -1);
else
- newValue = xmlStrdup(oldValue);
+ node->name = xmlStrdup(node->name);
+ if (node->name == NULL)
+ ret = -1;
+ }
+
+ if ((node->content != NULL) &&
+ ((node->type == XML_TEXT_NODE) ||
+ (node->type == XML_CDATA_SECTION_NODE)) &&
+ (xmlDictOwns(oldDict, node->content))) {
+ node->content = xmlStrdup(node->content);
+ if (node->content == NULL)
+ ret = -1;
+ }
+ }
+
+ switch (node->type) {
+ case XML_ATTRIBUTE_NODE: {
+ xmlAttrPtr attr = (xmlAttrPtr) node;
+
+ /*
+ * Handle IDs
+ *
+ * TODO: ID attributes should also be added to the new
+ * document, but it's not clear how to handle clashes.
+ */
+ if (attr->atype == XML_ATTRIBUTE_ID)
+ xmlRemoveID(oldDoc, attr);
+
+ break;
}
+
+ case XML_ENTITY_REF_NODE:
+ /*
+ * Handle entity references
+ */
+ node->children = NULL;
+ node->last = NULL;
+ node->content = NULL;
+
+ if ((doc != NULL) &&
+ ((doc->intSubset != NULL) || (doc->extSubset != NULL))) {
+ xmlEntityPtr ent;
+
+ /*
+ * Assign new entity node if available
+ */
+ ent = xmlGetDocEntity(doc, node->name);
+ if (ent != NULL) {
+ node->children = (xmlNodePtr) ent;
+ node->last = (xmlNodePtr) ent;
+ node->content = ent->content;
+ }
+ }
+
+ break;
+
+ case XML_DTD_NODE:
+ if (oldDoc != NULL) {
+ if (oldDoc->intSubset == (xmlDtdPtr) node)
+ oldDoc->intSubset = NULL;
+ if (oldDoc->extSubset == (xmlDtdPtr) node)
+ oldDoc->extSubset = NULL;
+ }
+
+ break;
+
+ case XML_ENTITY_DECL:
+ xmlRemoveEntity((xmlEntityPtr) node);
+ break;
+
+ /*
+ * TODO:
+ * - Remove element decls from doc->elements
+ * - Remove attribtue decls form doc->attributes
+ */
+
+ default:
+ break;
}
- return newValue;
+
+ /*
+ * Set new document
+ */
+ node->doc = doc;
+
+ return(ret);
}
/**
* xmlSetTreeDoc:
- * @tree: the top element
- * @doc: the document
+ * @tree: root of a subtree
+ * @doc: new document
+ *
+ * This is an internal function which shouldn't be used. It is
+ * invoked by functions like xmlAddChild, xmlAddSibling or
+ * xmlReplaceNode. @tree must be the root node of an unlinked
+ * subtree.
+ *
+ * Associate all nodes in a tree with a new document.
+ *
+ * Also copy strings from the old document's dictionary and
+ * remove ID attributes from the old ID table.
*
- * update all nodes under the tree to point to the right document
+ * Returns 0 on success. If a memory allocation fails, returns -1.
+ * The whole tree will be updated on failure but some strings
+ * may be lost.
*/
-void
+int
xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
- xmlAttrPtr prop;
+ int ret = 0;
if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL))
- return;
- if (tree->doc != doc) {
- xmlDictPtr oldTreeDict = tree->doc ? tree->doc->dict : NULL;
- xmlDictPtr newDict = doc ? doc->dict : NULL;
-
- if(tree->type == XML_ELEMENT_NODE) {
- prop = tree->properties;
- while (prop != NULL) {
- if (prop->atype == XML_ATTRIBUTE_ID) {
- xmlRemoveID(tree->doc, prop);
- }
+ return(0);
+ if (tree->doc == doc)
+ return(0);
- if (prop->doc != doc) {
- xmlDictPtr oldPropDict = prop->doc ? prop->doc->dict : NULL;
- prop->name = _copyStringForNewDictIfNeeded(oldPropDict, newDict, prop->name);
- prop->doc = doc;
- }
- xmlSetListDoc(prop->children, doc);
+ if (tree->type == XML_ELEMENT_NODE) {
+ xmlAttrPtr prop = tree->properties;
- /*
- * TODO: ID attributes should be also added to the new
- * document, but this breaks things like xmlReplaceNode.
- * The underlying problem is that xmlRemoveID is only called
- * if a node is destroyed, not if it's unlinked.
- */
-#if 0
- if (xmlIsID(doc, tree, prop)) {
- xmlChar *idVal = xmlNodeListGetString(doc, prop->children,
- 1);
- xmlAddID(NULL, doc, idVal, prop);
- }
-#endif
+ while (prop != NULL) {
+ if (prop->children != NULL) {
+ if (xmlSetListDoc(prop->children, doc) < 0)
+ ret = -1;
+ }
- prop = prop->next;
- }
- }
- if (tree->type == XML_ENTITY_REF_NODE) {
- /*
- * Clear 'children' which points to the entity declaration
- * from the original document.
- */
- tree->children = NULL;
- } else if (tree->children != NULL) {
- xmlSetListDoc(tree->children, doc);
+ if (xmlNodeSetDoc((xmlNodePtr) prop, doc) < 0)
+ ret = -1;
+
+ prop = prop->next;
}
+ }
- tree->name = _copyStringForNewDictIfNeeded(oldTreeDict, newDict, tree->name);
- tree->content = (xmlChar *)_copyStringForNewDictIfNeeded(oldTreeDict, NULL, tree->content);
- /* FIXME: tree->ns should be updated as in xmlStaticCopyNode(). */
- tree->doc = doc;
+ if ((tree->children != NULL) &&
+ (tree->type != XML_ENTITY_REF_NODE)) {
+ if (xmlSetListDoc(tree->children, doc) < 0)
+ ret = -1;
}
+
+ if (xmlNodeSetDoc(tree, doc) < 0)
+ ret = -1;
+
+ return(ret);
}
/**
* xmlSetListDoc:
- * @list: the first element
- * @doc: the document
+ * @list: a node list
+ * @doc: new document
+ *
+ * Associate all subtrees in @list with a new document.
*
- * update all nodes in the list to point to the right document
+ * Internal function, see xmlSetTreeDoc.
+ *
+ * Returns 0 on success. If a memory allocation fails, returns -1.
+ * All subtrees will be updated on failure but some strings
+ * may be lost.
*/
-void
+int
xmlSetListDoc(xmlNodePtr list, xmlDocPtr doc) {
xmlNodePtr cur;
+ int ret = 0;
if ((list == NULL) || (list->type == XML_NAMESPACE_DECL))
- return;
+ return(0);
+
cur = list;
while (cur != NULL) {
- if (cur->doc != doc)
- xmlSetTreeDoc(cur, doc);
+ if (cur->doc != doc) {
+ if (xmlSetTreeDoc(cur, doc) < 0)
+ ret = -1;
+ }
cur = cur->next;
}
+
+ return(ret);
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
/**
* xmlNewChild:
* @parent: the parent node
- * @ns: a namespace if any
+ * @ns: a namespace (optional)
* @name: the name of the child
- * @content: the XML content of the child if any.
+ * @content: text content with XML references (optional)
*
- * Creation of a new child element, added at the end of @parent children list.
- * @ns and @content parameters are optional (NULL). If @ns is NULL, the newly
- * created element inherits the namespace of @parent. If @content is non NULL,
- * a child list containing the TEXTs and ENTITY_REFs node will be created.
- * NOTE: @content is supposed to be a piece of XML CDATA, so it allows entity
- * references. XML special chars must be escaped first by using
- * xmlEncodeEntitiesReentrant(), or xmlNewTextChild() should be used.
+ * Create a new child element and append it to a parent element.
*
- * Returns a pointer to the new node object.
+ * If @ns is NULL, the newly created element inherits the namespace
+ * of the parent.
+ *
+ * If provided, @content is expected to be a valid XML attribute
+ * value possibly containing character and entity references. Text
+ * and entity reference node will be added to the child element,
+ * see xmlNewDocNode.
+ *
+ * Returns a pointer to the new node object or NULL if arguments
+ * are invalid or a memory allocation failed.
*/
xmlNodePtr
xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
const xmlChar *name, const xmlChar *content) {
xmlNodePtr cur, prev;
- if (parent == NULL) {
+ if ((parent == NULL) || (name == NULL))
return(NULL);
- }
- if (name == NULL) {
- return(NULL);
- }
+ switch (parent->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_DOCUMENT_FRAG_NODE:
+ break;
- /*
- * Allocate a new node
- */
- if (parent->type == XML_ELEMENT_NODE) {
- if (ns == NULL)
- cur = xmlNewDocNode(parent->doc, parent->ns, name, content);
- else
- cur = xmlNewDocNode(parent->doc, ns, name, content);
- } else if ((parent->type == XML_DOCUMENT_NODE) ||
- (parent->type == XML_HTML_DOCUMENT_NODE)) {
- if (ns == NULL)
- cur = xmlNewDocNode((xmlDocPtr) parent, NULL, name, content);
- else
- cur = xmlNewDocNode((xmlDocPtr) parent, ns, name, content);
- } else if (parent->type == XML_DOCUMENT_FRAG_NODE) {
- cur = xmlNewDocNode( parent->doc, ns, name, content);
- } else {
- return(NULL);
+ case XML_ELEMENT_NODE:
+ if (ns == NULL)
+ ns = parent->ns;
+ break;
+
+ default:
+ return(NULL);
}
- if (cur == NULL) return(NULL);
+
+ cur = xmlNewDocNode(parent->doc, ns, name, content);
+ if (cur == NULL)
+ return(NULL);
/*
* add the new element at the end of the children list.
*/
- cur->type = XML_ELEMENT_NODE;
cur->parent = parent;
- cur->doc = parent->doc;
if (parent->children == NULL) {
parent->children = cur;
parent->last = cur;
@@ -2926,261 +2986,274 @@ xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
}
#endif /* LIBXML_TREE_ENABLED */
-/**
- * xmlAddPropSibling:
- * @prev: the attribute to which @prop is added after
- * @cur: the base attribute passed to calling function
- * @prop: the new attribute
- *
- * Add a new attribute after @prev using @cur as base attribute.
- * When inserting before @cur, @prev is passed as @cur->prev.
- * When inserting after @cur, @prev is passed as @cur.
- * If an existing attribute is found it is destroyed prior to adding @prop.
- *
- * See the note regarding namespaces in xmlAddChild.
- *
- * Returns the attribute being inserted or NULL in case of error.
- */
+static void
+xmlTextSetContent(xmlNodePtr text, xmlChar *content) {
+ if ((text->content != NULL) &&
+ (text->content != (xmlChar *) &text->properties)) {
+ xmlDocPtr doc = text->doc;
+
+ if ((doc == NULL) ||
+ (doc->dict == NULL) ||
+ (!xmlDictOwns(doc->dict, text->content)))
+ xmlFree(text->content);
+ }
+
+ text->content = content;
+ text->properties = NULL;
+}
+
+static int
+xmlTextAddContent(xmlNodePtr text, const xmlChar *content, int len) {
+ xmlChar *merged;
+
+ if (content == NULL)
+ return(0);
+
+ merged = xmlStrncatNew(text->content, content, len);
+ if (merged == NULL)
+ return(-1);
+
+ xmlTextSetContent(text, merged);
+ return(0);
+}
+
static xmlNodePtr
-xmlAddPropSibling(xmlNodePtr prev, xmlNodePtr cur, xmlNodePtr prop) {
- xmlAttrPtr attr;
+xmlInsertProp(xmlDocPtr doc, xmlNodePtr cur, xmlNodePtr parent,
+ xmlNodePtr prev, xmlNodePtr next) {
+ xmlAttrPtr attr;
- if ((cur == NULL) || (cur->type != XML_ATTRIBUTE_NODE) ||
- (prop == NULL) || (prop->type != XML_ATTRIBUTE_NODE) ||
- ((prev != NULL) && (prev->type != XML_ATTRIBUTE_NODE)))
- return(NULL);
+ if (((prev != NULL) && (prev->type != XML_ATTRIBUTE_NODE)) ||
+ ((next != NULL) && (next->type != XML_ATTRIBUTE_NODE)))
+ return(NULL);
- /* check if an attribute with the same name exists */
- if (prop->ns == NULL)
- attr = xmlHasNsProp(cur->parent, prop->name, NULL);
- else
- attr = xmlHasNsProp(cur->parent, prop->name, prop->ns->href);
+ /* check if an attribute with the same name exists */
+ attr = xmlGetPropNodeInternal(parent, cur->name,
+ cur->ns ? cur->ns->href : NULL, 0);
- if (prop->doc != cur->doc) {
- xmlSetTreeDoc(prop, cur->doc);
- }
- prop->parent = cur->parent;
- prop->prev = prev;
- if (prev != NULL) {
- prop->next = prev->next;
- prev->next = prop;
- if (prop->next)
- prop->next->prev = prop;
- } else {
- prop->next = cur;
- cur->prev = prop;
+ xmlUnlinkNodeInternal(cur);
+
+ if (cur->doc != doc) {
+ if (xmlSetTreeDoc(cur, doc) < 0)
+ return(NULL);
+ }
+
+ cur->parent = parent;
+ cur->prev = prev;
+ cur->next = next;
+
+ if (prev == NULL) {
+ if (parent != NULL)
+ parent->properties = (xmlAttrPtr) cur;
+ } else {
+ prev->next = cur;
+ }
+ if (next != NULL) {
+ next->prev = cur;
+ }
+
+ if ((attr != NULL) && (attr != (xmlAttrPtr) cur)) {
+ /* different instance, destroy it (attributes must be unique) */
+ xmlRemoveProp((xmlAttrPtr) attr);
+ }
+
+ return cur;
+}
+
+static xmlNodePtr
+xmlInsertNode(xmlDocPtr doc, xmlNodePtr cur, xmlNodePtr parent,
+ xmlNodePtr prev, xmlNodePtr next, int coalesce) {
+ xmlNodePtr oldParent;
+
+ if (cur->type == XML_ATTRIBUTE_NODE)
+ return xmlInsertProp(doc, cur, parent, prev, next);
+
+ /*
+ * Coalesce text nodes
+ */
+ if ((coalesce) && (cur->type == XML_TEXT_NODE)) {
+ if ((prev != NULL) && (prev->type == XML_TEXT_NODE) &&
+ (prev->name == cur->name)) {
+ if (xmlTextAddContent(prev, cur->content, -1) < 0)
+ return(NULL);
+ xmlUnlinkNodeInternal(cur);
+ xmlFreeNode(cur);
+ return(prev);
}
- if (prop->prev == NULL && prop->parent != NULL)
- prop->parent->properties = (xmlAttrPtr) prop;
- if ((attr != NULL) && (attr->type != XML_ATTRIBUTE_DECL)) {
- /* different instance, destroy it (attributes must be unique) */
- xmlRemoveProp((xmlAttrPtr) attr);
+
+ if ((next != NULL) && (next->type == XML_TEXT_NODE) &&
+ (next->name == cur->name)) {
+ if (cur->content != NULL) {
+ xmlChar *merged;
+
+ merged = xmlStrncatNew(cur->content, next->content, -1);
+ if (merged == NULL)
+ return(NULL);
+ xmlTextSetContent(next, merged);
+ }
+
+ xmlUnlinkNodeInternal(cur);
+ xmlFreeNode(cur);
+ return(next);
}
- return prop;
+ }
+
+ /* Unlink */
+ oldParent = cur->parent;
+ if (oldParent != NULL) {
+ if (oldParent->children == cur)
+ oldParent->children = cur->next;
+ if (oldParent->last == cur)
+ oldParent->last = cur->prev;
+ }
+ if (cur->next != NULL)
+ cur->next->prev = cur->prev;
+ if (cur->prev != NULL)
+ cur->prev->next = cur->next;
+
+ if (cur->doc != doc) {
+ if (xmlSetTreeDoc(cur, doc) < 0) {
+ /*
+ * We shouldn't make any modifications to the inserted
+ * tree if a memory allocation fails, but that's hard to
+ * implement. The tree has been moved to the target
+ * document now but some contents are corrupted.
+ * Unlinking is the best we can do.
+ */
+ cur->parent = NULL;
+ cur->prev = NULL;
+ cur->next = NULL;
+ return(NULL);
+ }
+ }
+
+ cur->parent = parent;
+ cur->prev = prev;
+ cur->next = next;
+
+ if (prev == NULL) {
+ if (parent != NULL)
+ parent->children = cur;
+ } else {
+ prev->next = cur;
+ }
+ if (next == NULL) {
+ if (parent != NULL)
+ parent->last = cur;
+ } else {
+ next->prev = cur;
+ }
+
+ return(cur);
}
/**
* xmlAddNextSibling:
- * @cur: the child node
- * @elem: the new node
+ * @prev: the target node
+ * @cur: the new node
*
- * Add a new node @elem as the next sibling of @cur
- * If the new node was already inserted in a document it is
- * first unlinked from its existing context.
- * As a result of text merging @elem may be freed.
- * If the new node is ATTRIBUTE, it is added into properties instead of children.
- * If there is an attribute with equal name, it is first destroyed.
+ * Unlinks @cur and inserts it as next sibling after @prev.
*
- * See the note regarding namespaces in xmlAddChild.
+ * Unlike xmlAddChild this function does not merge text nodes.
*
- * Returns the new node or NULL in case of error.
+ * If @cur is an attribute node, it is inserted after attribute
+ * @prev. If the attribute list contains an attribute with a name
+ * matching @cur, the old attribute is destroyed.
+ *
+ * See the notes in xmlAddChild.
+ *
+ * Returns @cur or a sibling if @cur was merged. Returns NULL
+ * if arguments are invalid or a memory allocation failed.
*/
xmlNodePtr
-xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
- if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
- return(NULL);
- }
- if ((elem == NULL) || (elem->type == XML_NAMESPACE_DECL)) {
- return(NULL);
- }
-
- if (cur == elem) {
+xmlAddNextSibling(xmlNodePtr prev, xmlNodePtr cur) {
+ if ((prev == NULL) || (prev->type == XML_NAMESPACE_DECL) ||
+ (cur == NULL) || (cur->type == XML_NAMESPACE_DECL) ||
+ (cur == prev))
return(NULL);
- }
-
- xmlUnlinkNode(elem);
- if (elem->type == XML_TEXT_NODE) {
- if (cur->type == XML_TEXT_NODE) {
- xmlNodeAddContent(cur, elem->content);
- xmlFreeNode(elem);
- return(cur);
- }
- if ((cur->next != NULL) && (cur->next->type == XML_TEXT_NODE) &&
- (cur->name == cur->next->name)) {
- xmlChar *tmp;
-
- tmp = xmlStrdup(elem->content);
- tmp = xmlStrcat(tmp, cur->next->content);
- xmlNodeSetContent(cur->next, tmp);
- xmlFree(tmp);
- xmlFreeNode(elem);
- return(cur->next);
- }
- } else if (elem->type == XML_ATTRIBUTE_NODE) {
- return xmlAddPropSibling(cur, cur, elem);
- }
+ if (cur == prev->next)
+ return(cur);
- if (elem->doc != cur->doc) {
- xmlSetTreeDoc(elem, cur->doc);
- }
- elem->parent = cur->parent;
- elem->prev = cur;
- elem->next = cur->next;
- cur->next = elem;
- if (elem->next != NULL)
- elem->next->prev = elem;
- if ((elem->parent != NULL) && (elem->parent->last == cur))
- elem->parent->last = elem;
- return(elem);
+ return(xmlInsertNode(prev->doc, cur, prev->parent, prev, prev->next, 0));
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
/**
* xmlAddPrevSibling:
- * @cur: the child node
- * @elem: the new node
+ * @next: the target node
+ * @cur: the new node
+ *
+ * Unlinks @cur and inserts it as previous sibling before @next.
*
- * Add a new node @elem as the previous sibling of @cur
- * merging adjacent TEXT nodes (@elem may be freed)
- * If the new node was already inserted in a document it is
- * first unlinked from its existing context.
- * If the new node is ATTRIBUTE, it is added into properties instead of children.
- * If there is an attribute with equal name, it is first destroyed.
+ * Unlike xmlAddChild this function does not merge text nodes.
*
- * See the note regarding namespaces in xmlAddChild.
+ * If @cur is an attribute node, it is inserted before attribute
+ * @next. If the attribute list contains an attribute with a name
+ * matching @cur, the old attribute is destroyed.
*
- * Returns the new node or NULL in case of error.
+ * See the notes in xmlAddChild.
+ *
+ * Returns @cur or a sibling if @cur was merged. Returns NULL
+ * if arguments are invalid or a memory allocation failed.
*/
xmlNodePtr
-xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
- if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
- return(NULL);
- }
- if ((elem == NULL) || (elem->type == XML_NAMESPACE_DECL)) {
+xmlAddPrevSibling(xmlNodePtr next, xmlNodePtr cur) {
+ if ((next == NULL) || (next->type == XML_NAMESPACE_DECL) ||
+ (cur == NULL) || (cur->type == XML_NAMESPACE_DECL) ||
+ (cur == next))
return(NULL);
- }
-
- if (cur == elem) {
- return(NULL);
- }
- xmlUnlinkNode(elem);
+ if (cur == next->prev)
+ return(cur);
- if (elem->type == XML_TEXT_NODE) {
- if (cur->type == XML_TEXT_NODE) {
- xmlChar *tmp;
-
- tmp = xmlStrdup(elem->content);
- tmp = xmlStrcat(tmp, cur->content);
- xmlNodeSetContent(cur, tmp);
- xmlFree(tmp);
- xmlFreeNode(elem);
- return(cur);
- }
- if ((cur->prev != NULL) && (cur->prev->type == XML_TEXT_NODE) &&
- (cur->name == cur->prev->name)) {
- xmlNodeAddContent(cur->prev, elem->content);
- xmlFreeNode(elem);
- return(cur->prev);
- }
- } else if (elem->type == XML_ATTRIBUTE_NODE) {
- return xmlAddPropSibling(cur->prev, cur, elem);
- }
-
- if (elem->doc != cur->doc) {
- xmlSetTreeDoc(elem, cur->doc);
- }
- elem->parent = cur->parent;
- elem->next = cur;
- elem->prev = cur->prev;
- cur->prev = elem;
- if (elem->prev != NULL)
- elem->prev->next = elem;
- if ((elem->parent != NULL) && (elem->parent->children == cur)) {
- elem->parent->children = elem;
- }
- return(elem);
+ return(xmlInsertNode(next->doc, cur, next->parent, next->prev, next, 0));
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlAddSibling:
- * @cur: the child node
- * @elem: the new node
+ * @node: the target node
+ * @cur: the new node
*
- * Add a new element @elem to the list of siblings of @cur
- * merging adjacent TEXT nodes (@elem may be freed)
- * If the new element was already inserted in a document it is
- * first unlinked from its existing context.
+ * Unlinks @cur and inserts it as last sibling of @node.
*
- * See the note regarding namespaces in xmlAddChild.
+ * If @cur is a text node, it may be merged with an adjacent text
+ * node and freed. In this case the text node containing the merged
+ * content is returned.
*
- * Returns the new element or NULL in case of error.
+ * If @cur is an attribute node, it is appended to the attribute
+ * list containing @node. If the attribute list contains an attribute
+ * with a name matching @cur, the old attribute is destroyed.
+ *
+ * See the notes in xmlAddChild.
+ *
+ * Returns @cur or a sibling if @cur was merged. Returns NULL
+ * if arguments are invalid or a memory allocation failed.
*/
xmlNodePtr
-xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
- xmlNodePtr parent;
-
- if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
- return(NULL);
- }
-
- if ((elem == NULL) || (elem->type == XML_NAMESPACE_DECL)) {
- return(NULL);
- }
-
- if (cur == elem) {
+xmlAddSibling(xmlNodePtr node, xmlNodePtr cur) {
+ if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) ||
+ (cur == NULL) || (cur->type == XML_NAMESPACE_DECL) ||
+ (cur == node))
return(NULL);
- }
/*
* Constant time is we can rely on the ->parent->last to find
* the last sibling.
*/
- if ((cur->type != XML_ATTRIBUTE_NODE) && (cur->parent != NULL) &&
- (cur->parent->children != NULL) &&
- (cur->parent->last != NULL) &&
- (cur->parent->last->next == NULL)) {
- cur = cur->parent->last;
+ if ((node->type != XML_ATTRIBUTE_NODE) && (node->parent != NULL)) {
+ if (node->parent->last != NULL)
+ node = node->parent->last;
} else {
- while (cur->next != NULL) cur = cur->next;
- }
-
- xmlUnlinkNode(elem);
-
- if ((cur->type == XML_TEXT_NODE) && (elem->type == XML_TEXT_NODE) &&
- (cur->name == elem->name)) {
- xmlNodeAddContent(cur, elem->content);
- xmlFreeNode(elem);
- return(cur);
- } else if (elem->type == XML_ATTRIBUTE_NODE) {
- return xmlAddPropSibling(cur, cur, elem);
+ while (node->next != NULL)
+ node = node->next;
}
- if (elem->doc != cur->doc) {
- xmlSetTreeDoc(elem, cur->doc);
- }
- parent = cur->parent;
- elem->prev = cur;
- elem->next = NULL;
- elem->parent = parent;
- cur->next = elem;
- if (parent != NULL)
- parent->last = elem;
+ if (cur == node)
+ return(cur);
- return(elem);
+ return(xmlInsertNode(node->doc, cur, node->parent, node, NULL, 1));
}
/**
@@ -3188,16 +3261,17 @@ xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
* @parent: the parent node
* @cur: the first node in the list
*
- * Add a list of node at the end of the child list of the parent
- * merging adjacent TEXT nodes (@cur may be freed)
+ * Append a node list to another node.
*
- * See the note regarding namespaces in xmlAddChild.
+ * See xmlAddChild.
*
* Returns the last child or NULL in case of error.
*/
xmlNodePtr
xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
+ xmlNodePtr iter;
xmlNodePtr prev;
+ int oom;
if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
return(NULL);
@@ -3207,9 +3281,15 @@ xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
return(NULL);
}
- if ((cur->doc != NULL) && (parent->doc != NULL) &&
- (cur->doc != parent->doc)) {
+ oom = 0;
+ for (iter = cur; iter != NULL; iter = iter->next) {
+ if (iter->doc != parent->doc) {
+ if (xmlSetTreeDoc(iter, parent->doc) < 0)
+ oom = 1;
+ }
}
+ if (oom)
+ return(NULL);
/*
* add the first element at the end of the children list.
@@ -3218,40 +3298,36 @@ xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
if (parent->children == NULL) {
parent->children = cur;
} else {
+ prev = parent->last;
+
/*
* If cur and parent->last both are TEXT nodes, then merge them.
*/
if ((cur->type == XML_TEXT_NODE) &&
- (parent->last->type == XML_TEXT_NODE) &&
- (cur->name == parent->last->name)) {
- xmlNodeAddContent(parent->last, cur->content);
+ (prev->type == XML_TEXT_NODE) &&
+ (cur->name == prev->name)) {
+ xmlNodePtr next;
+
+ if (xmlTextAddContent(prev, cur->content, -1) < 0)
+ return(NULL);
+ next = cur->next;
+ xmlFreeNode(cur);
/*
* if it's the only child, nothing more to be done.
*/
- if (cur->next == NULL) {
- xmlFreeNode(cur);
- return(parent->last);
- }
- prev = cur;
- cur = cur->next;
- xmlFreeNode(prev);
+ if (next == NULL)
+ return(prev);
+ cur = next;
}
- prev = parent->last;
+
prev->next = cur;
cur->prev = prev;
}
while (cur->next != NULL) {
cur->parent = parent;
- if (cur->doc != parent->doc) {
- xmlSetTreeDoc(cur, parent->doc);
- }
cur = cur->next;
}
cur->parent = parent;
- /* the parent may not be linked to a doc ! */
- if (cur->doc != parent->doc) {
- xmlSetTreeDoc(cur, parent->doc);
- }
parent->last = cur;
return(cur);
@@ -3262,130 +3338,87 @@ xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
* @parent: the parent node
* @cur: the child node
*
- * Add a new node to @parent, at the end of the child (or property) list
- * merging adjacent TEXT nodes (in which case @cur is freed)
- * If the new node is ATTRIBUTE, it is added into properties instead of children.
- * If there is an attribute with equal name, it is first destroyed.
+ * Unlink @cur and append it to the children of @parent.
*
- * All tree manipulation functions can safely move nodes within a document.
- * But when moving nodes from one document to another, references to
- * namespaces in element or attribute nodes are NOT fixed. In this case,
- * you MUST call xmlReconciliateNs after the move operation to avoid
- * memory errors.
+ * If @cur is a text node, it may be merged with an adjacent text
+ * node and freed. In this case the text node containing the merged
+ * content is returned.
*
- * Returns the child or NULL in case of error.
+ * If @cur is an attribute node, it is appended to the attributes of
+ * @parent. If the attribute list contains an attribute with a name
+ * matching @elem, the old attribute is destroyed.
+ *
+ * General notes:
+ *
+ * Move operations like xmlAddChild can cause element or attribute
+ * nodes to reference namespaces that aren't declared in one of
+ * their ancestors. This can lead to use-after-free errors if the
+ * elements containing the declarations are freed later, especially
+ * when moving nodes from one document to another. You should
+ * consider calling xmlReconciliateNs after a move operation to
+ * normalize namespaces. Another option is to call
+ * xmlDOMWrapAdoptNode with the target parent before moving a node.
+ *
+ * For the most part, move operations don't check whether the
+ * resulting tree structure is valid. Users must make sure that
+ * parent nodes only receive children of valid types. Inserted
+ * child nodes must never be an ancestor of the parent node to
+ * avoid cycles in the tree structure. In general, only
+ * document, document fragments, elements and attributes
+ * should be used as parent nodes.
+ *
+ * When moving a node between documents and a memory allocation
+ * fails, the node's content will be corrupted and it will be
+ * unlinked. In this case, the node must be freed manually.
+ *
+ * Moving DTDs between documents isn't supported.
+ *
+ * Returns @elem or a sibling if @elem was merged. Returns NULL
+ * if arguments are invalid or a memory allocation failed.
*/
xmlNodePtr
xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
xmlNodePtr prev;
- if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
- return(NULL);
- }
-
- if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
- return(NULL);
- }
-
- if (parent == cur) {
- return(NULL);
- }
- /*
- * If cur is a TEXT node, merge its content with adjacent TEXT nodes
- * cur is then freed.
- */
- if (cur->type == XML_TEXT_NODE) {
- if ((parent->type == XML_TEXT_NODE) &&
- (parent->content != NULL) &&
- (parent->name == cur->name)) {
- xmlNodeAddContent(parent, cur->content);
- xmlFreeNode(cur);
- return(parent);
- }
- if ((parent->last != NULL) && (parent->last->type == XML_TEXT_NODE) &&
- (parent->last->name == cur->name) &&
- (parent->last != cur)) {
- xmlNodeAddContent(parent->last, cur->content);
- xmlFreeNode(cur);
- return(parent->last);
- }
- }
+ if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL) ||
+ (cur == NULL) || (cur->type == XML_NAMESPACE_DECL) ||
+ (parent == cur))
+ return(NULL);
/*
- * add the new element at the end of the children list.
+ * If parent is a text node, call xmlTextAddContent. This
+ * undocumented quirk should probably be removed.
*/
- prev = cur->parent;
- cur->parent = parent;
- if (cur->doc != parent->doc) {
- xmlSetTreeDoc(cur, parent->doc);
+ if (parent->type == XML_TEXT_NODE) {
+ if (xmlTextAddContent(parent, cur->content, -1) < 0)
+ return(NULL);
+ xmlFreeNode(cur);
+ return(parent);
}
- /* this check prevents a loop on tree-traversions if a developer
- * tries to add a node to its parent multiple times
- */
- if (prev == parent)
- return(cur);
- /*
- * Coalescing
- */
- if ((parent->type == XML_TEXT_NODE) &&
- (parent->content != NULL) &&
- (parent != cur)) {
- xmlNodeAddContent(parent, cur->content);
- xmlFreeNode(cur);
- return(parent);
- }
if (cur->type == XML_ATTRIBUTE_NODE) {
- if (parent->type != XML_ELEMENT_NODE)
- return(NULL);
- if (parent->properties != NULL) {
- /* check if an attribute with the same name exists */
- xmlAttrPtr lastattr;
-
- if (cur->ns == NULL)
- lastattr = xmlHasNsProp(parent, cur->name, NULL);
- else
- lastattr = xmlHasNsProp(parent, cur->name, cur->ns->href);
- if ((lastattr != NULL) && (lastattr != (xmlAttrPtr) cur) && (lastattr->type != XML_ATTRIBUTE_DECL)) {
- /* different instance, destroy it (attributes must be unique) */
- xmlUnlinkNode((xmlNodePtr) lastattr);
- xmlFreeProp(lastattr);
- }
- if (lastattr == (xmlAttrPtr) cur)
- return(cur);
-
- }
- if (parent->properties == NULL) {
- parent->properties = (xmlAttrPtr) cur;
- } else {
- /* find the end */
- xmlAttrPtr lastattr = parent->properties;
- while (lastattr->next != NULL) {
- lastattr = lastattr->next;
- }
- lastattr->next = (xmlAttrPtr) cur;
- ((xmlAttrPtr) cur)->prev = lastattr;
- }
+ prev = (xmlNodePtr) parent->properties;
+ if (prev != NULL) {
+ while (prev->next != NULL)
+ prev = prev->next;
+ }
} else {
- if (parent->children == NULL) {
- parent->children = cur;
- parent->last = cur;
- } else {
- prev = parent->last;
- prev->next = cur;
- cur->prev = prev;
- parent->last = cur;
- }
+ prev = parent->last;
}
- return(cur);
+
+ if (cur == prev)
+ return(cur);
+
+ return(xmlInsertNode(parent->doc, cur, parent, prev, NULL, 1));
}
/**
* xmlGetLastChild:
* @parent: the parent node
*
- * Search the last child of a node.
- * Returns the last child or NULL if none.
+ * Find the last child of a node.
+ *
+ * Returns the last child or NULL if parent has no children.
*/
xmlNodePtr
xmlGetLastChild(const xmlNode *parent) {
@@ -3404,13 +3437,12 @@ xmlGetLastChild(const xmlNode *parent) {
* xmlChildElementCount:
* @parent: the parent node
*
- * Finds the current number of child nodes of that element which are
- * element nodes.
- * Note the handling of entities references is different than in
- * the W3C DOM element traversal spec since we don't have back reference
- * from entities content to entities references.
+ * Count the number of child nodes which are elements.
*
- * Returns the count of element child or 0 if not available
+ * Note that entity references are not expanded.
+ *
+ * Returns the number of element children or 0 if arguments are
+ * invalid.
*/
unsigned long
xmlChildElementCount(xmlNodePtr parent) {
@@ -3421,10 +3453,10 @@ xmlChildElementCount(xmlNodePtr parent) {
return(0);
switch (parent->type) {
case XML_ELEMENT_NODE:
- case XML_ENTITY_NODE:
case XML_DOCUMENT_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_HTML_DOCUMENT_NODE:
+ case XML_ENTITY_DECL:
cur = parent->children;
break;
default:
@@ -3442,12 +3474,11 @@ xmlChildElementCount(xmlNodePtr parent) {
* xmlFirstElementChild:
* @parent: the parent node
*
- * Finds the first child node of that element which is a Element node
- * Note the handling of entities references is different than in
- * the W3C DOM element traversal spec since we don't have back reference
- * from entities content to entities references.
+ * Find the first child node which is an element.
*
- * Returns the first element child or NULL if not available
+ * Note that entity references are not expanded.
+ *
+ * Returns the first element or NULL if parent has no children.
*/
xmlNodePtr
xmlFirstElementChild(xmlNodePtr parent) {
@@ -3457,10 +3488,10 @@ xmlFirstElementChild(xmlNodePtr parent) {
return(NULL);
switch (parent->type) {
case XML_ELEMENT_NODE:
- case XML_ENTITY_NODE:
case XML_DOCUMENT_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_HTML_DOCUMENT_NODE:
+ case XML_ENTITY_DECL:
cur = parent->children;
break;
default:
@@ -3478,12 +3509,11 @@ xmlFirstElementChild(xmlNodePtr parent) {
* xmlLastElementChild:
* @parent: the parent node
*
- * Finds the last child node of that element which is a Element node
- * Note the handling of entities references is different than in
- * the W3C DOM element traversal spec since we don't have back reference
- * from entities content to entities references.
+ * Find the last child node which is an element.
*
- * Returns the last element child or NULL if not available
+ * Note that entity references are not expanded.
+ *
+ * Returns the last element or NULL if parent has no children.
*/
xmlNodePtr
xmlLastElementChild(xmlNodePtr parent) {
@@ -3493,10 +3523,10 @@ xmlLastElementChild(xmlNodePtr parent) {
return(NULL);
switch (parent->type) {
case XML_ELEMENT_NODE:
- case XML_ENTITY_NODE:
case XML_DOCUMENT_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_HTML_DOCUMENT_NODE:
+ case XML_ENTITY_DECL:
cur = parent->last;
break;
default:
@@ -3514,13 +3544,11 @@ xmlLastElementChild(xmlNodePtr parent) {
* xmlPreviousElementSibling:
* @node: the current node
*
- * Finds the first closest previous sibling of the node which is an
- * element node.
- * Note the handling of entities references is different than in
- * the W3C DOM element traversal spec since we don't have back reference
- * from entities content to entities references.
+ * Find the closest preceding sibling which is a element.
*
- * Returns the previous element sibling or NULL if not available
+ * Note that entity references are not expanded.
+ *
+ * Returns the sibling or NULL if no sibling was found.
*/
xmlNodePtr
xmlPreviousElementSibling(xmlNodePtr node) {
@@ -3531,7 +3559,6 @@ xmlPreviousElementSibling(xmlNodePtr node) {
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
case XML_XINCLUDE_START:
@@ -3553,13 +3580,11 @@ xmlPreviousElementSibling(xmlNodePtr node) {
* xmlNextElementSibling:
* @node: the current node
*
- * Finds the first closest next sibling of the node which is an
- * element node.
- * Note the handling of entities references is different than in
- * the W3C DOM element traversal spec since we don't have back reference
- * from entities content to entities references.
+ * Find the closest following sibling which is a element.
+ *
+ * Note that entity references are not expanded.
*
- * Returns the next element sibling or NULL if not available
+ * Returns the sibling or NULL if no sibling was found.
*/
xmlNodePtr
xmlNextElementSibling(xmlNodePtr node) {
@@ -3570,7 +3595,6 @@ xmlNextElementSibling(xmlNodePtr node) {
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
case XML_DTD_NODE:
@@ -3595,8 +3619,7 @@ xmlNextElementSibling(xmlNodePtr node) {
* xmlFreeNodeList:
* @cur: the first node in the list
*
- * Free a node and all its siblings, this is a recursive behaviour, all
- * the children are freed too.
+ * Free a node list including all children.
*/
void
xmlFreeNodeList(xmlNodePtr cur) {
@@ -3626,8 +3649,14 @@ xmlFreeNodeList(xmlNodePtr cur) {
if ((cur->type == XML_DOCUMENT_NODE) ||
(cur->type == XML_HTML_DOCUMENT_NODE)) {
xmlFreeDoc((xmlDocPtr) cur);
- } else if (cur->type != XML_DTD_NODE) {
-
+ } else if (cur->type == XML_DTD_NODE) {
+ /*
+ * TODO: We should consider freeing the DTD if it isn't
+ * referenced from doc->intSubset or doc->extSubset.
+ */
+ cur->prev = NULL;
+ cur->next = NULL;
+ } else {
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
xmlDeregisterNodeDefaultValue(cur);
@@ -3678,8 +3707,10 @@ xmlFreeNodeList(xmlNodePtr cur) {
* xmlFreeNode:
* @cur: the node
*
- * Free a node, this is a recursive behaviour, all the children are freed too.
- * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
+ * Free a node including all the children.
+ *
+ * This doesn't unlink the node from the tree. Call xmlUnlinkNode first
+ * unless @cur is a root node.
*/
void
xmlFreeNode(xmlNodePtr cur) {
@@ -3742,54 +3773,16 @@ xmlFreeNode(xmlNodePtr cur) {
}
/**
- * xmlUnlinkNode:
+ * xmlUnlinkNodeInternal:
* @cur: the node
*
- * Unlink a node from it's current context, the node is not freed
- * If one need to free the node, use xmlFreeNode() routine after the
- * unlink to discard it.
- * Note that namespace nodes can't be unlinked as they do not have
- * pointer to their parent.
+ * Unlink a node from its tree.
+ *
+ * This function only unlinks the node from the tree. It doesn't
+ * clear references to DTD nodes.
*/
-void
-xmlUnlinkNode(xmlNodePtr cur) {
- if (cur == NULL) {
- return;
- }
- if (cur->type == XML_NAMESPACE_DECL)
- return;
- if (cur->type == XML_DTD_NODE) {
- xmlDocPtr doc;
- doc = cur->doc;
- if (doc != NULL) {
- if (doc->intSubset == (xmlDtdPtr) cur)
- doc->intSubset = NULL;
- if (doc->extSubset == (xmlDtdPtr) cur)
- doc->extSubset = NULL;
- }
- }
- if (cur->type == XML_ENTITY_DECL) {
- xmlDocPtr doc;
- doc = cur->doc;
- if (doc != NULL) {
- if (doc->intSubset != NULL) {
- if (xmlHashLookup(doc->intSubset->entities, cur->name) == cur)
- xmlHashRemoveEntry(doc->intSubset->entities, cur->name,
- NULL);
- if (xmlHashLookup(doc->intSubset->pentities, cur->name) == cur)
- xmlHashRemoveEntry(doc->intSubset->pentities, cur->name,
- NULL);
- }
- if (doc->extSubset != NULL) {
- if (xmlHashLookup(doc->extSubset->entities, cur->name) == cur)
- xmlHashRemoveEntry(doc->extSubset->entities, cur->name,
- NULL);
- if (xmlHashLookup(doc->extSubset->pentities, cur->name) == cur)
- xmlHashRemoveEntry(doc->extSubset->pentities, cur->name,
- NULL);
- }
- }
- }
+static void
+xmlUnlinkNodeInternal(xmlNodePtr cur) {
if (cur->parent != NULL) {
xmlNodePtr parent;
parent = cur->parent;
@@ -3804,26 +3797,67 @@ xmlUnlinkNode(xmlNodePtr cur) {
}
cur->parent = NULL;
}
+
if (cur->next != NULL)
cur->next->prev = cur->prev;
if (cur->prev != NULL)
cur->prev->next = cur->next;
- cur->next = cur->prev = NULL;
+ cur->next = NULL;
+ cur->prev = NULL;
+}
+
+/**
+ * xmlUnlinkNode:
+ * @cur: the node
+ *
+ * Unlink a node from its tree.
+ *
+ * The node is not freed. Unless it is reinserted, it must be managed
+ * manually and freed eventually by calling xmlFreeNode.
+ */
+void
+xmlUnlinkNode(xmlNodePtr cur) {
+ if (cur == NULL)
+ return;
+
+ if (cur->type == XML_NAMESPACE_DECL)
+ return;
+
+ if (cur->type == XML_DTD_NODE) {
+ xmlDocPtr doc = cur->doc;
+
+ if (doc != NULL) {
+ if (doc->intSubset == (xmlDtdPtr) cur)
+ doc->intSubset = NULL;
+ if (doc->extSubset == (xmlDtdPtr) cur)
+ doc->extSubset = NULL;
+ }
+ }
+
+ if (cur->type == XML_ENTITY_DECL)
+ xmlRemoveEntity((xmlEntityPtr) cur);
+
+ xmlUnlinkNodeInternal(cur);
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
/**
* xmlReplaceNode:
* @old: the old node
- * @cur: the node
+ * @cur: the node (optional)
+ *
+ * Unlink the old node. If @cur is provided, it is unlinked and
+ * inserted in place of @old.
+ *
+ * It is an error if @old has no parent.
*
- * Unlink the old node from its current context, prune the new one
- * at the same place. If @cur was already inserted in a document it is
- * first unlinked from its existing context.
+ * Unlike xmlAddChild, this function doesn't merge text nodes or
+ * delete duplicate attributes.
*
- * See the note regarding namespaces in xmlAddChild.
+ * See the notes in xmlAddChild.
*
- * Returns the @old node
+ * Returns @old or NULL if arguments are invalid or a memory
+ * allocation failed.
*/
xmlNodePtr
xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
@@ -3833,20 +3867,19 @@ xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
return(NULL);
}
if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
+ /* Don't call xmlUnlinkNodeInternal to handle DTDs. */
xmlUnlinkNode(old);
return(old);
}
- if (cur == old) {
- return(old);
- }
if ((old->type==XML_ATTRIBUTE_NODE) && (cur->type!=XML_ATTRIBUTE_NODE)) {
return(old);
}
if ((cur->type==XML_ATTRIBUTE_NODE) && (old->type!=XML_ATTRIBUTE_NODE)) {
return(old);
}
- xmlUnlinkNode(cur);
- xmlSetTreeDoc(cur, old->doc);
+ xmlUnlinkNodeInternal(cur);
+ if (xmlSetTreeDoc(cur, old->doc) < 0)
+ return(NULL);
cur->parent = old->parent;
cur->next = old->next;
if (cur->next != NULL)
@@ -3881,9 +3914,10 @@ xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
* xmlCopyNamespace:
* @cur: the namespace
*
- * Do a copy of the namespace.
+ * Copy a namespace.
*
- * Returns: a new #xmlNsPtr, or NULL in case of error.
+ * Returns the copied namespace or NULL if a memory allocation
+ * failed.
*/
xmlNsPtr
xmlCopyNamespace(xmlNsPtr cur) {
@@ -3904,9 +3938,10 @@ xmlCopyNamespace(xmlNsPtr cur) {
* xmlCopyNamespaceList:
* @cur: the first namespace
*
- * Do a copy of an namespace list.
+ * Copy a namespace list.
*
- * Returns: a new #xmlNsPtr, or NULL in case of error.
+ * Returns the head of the copied list or NULL if a memory
+ * allocation failed.
*/
xmlNsPtr
xmlCopyNamespaceList(xmlNsPtr cur) {
@@ -3932,7 +3967,7 @@ xmlCopyNamespaceList(xmlNsPtr cur) {
static xmlAttrPtr
xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
- xmlAttrPtr ret;
+ xmlAttrPtr ret = NULL;
if (cur == NULL) return(NULL);
if ((target != NULL) && (target->type != XML_ELEMENT_NODE))
@@ -3952,15 +3987,20 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
if ((cur->ns != NULL) && (target != NULL)) {
xmlNsPtr ns;
+ int res;
- ns = xmlSearchNs(target->doc, target, cur->ns->prefix);
+ res = xmlSearchNsSafe(target, cur->ns->prefix, &ns);
+ if (res < 0)
+ goto error;
if (ns == NULL) {
/*
* Humm, we are copying an element whose namespace is defined
* out of the new tree scope. Search it in the original tree
* and add it at the top of the new tree
*/
- ns = xmlSearchNs(cur->doc, cur->parent, cur->ns->prefix);
+ res = xmlSearchNsSafe(cur->parent, cur->ns->prefix, &ns);
+ if (res < 0)
+ goto error;
if (ns != NULL) {
xmlNodePtr root = target;
xmlNodePtr pred = NULL;
@@ -3974,6 +4014,8 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
root = pred;
}
ret->ns = xmlNewNs(root, ns->href, ns->prefix);
+ if (ret->ns == NULL)
+ goto error;
}
} else {
/*
@@ -3989,7 +4031,9 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
* we are in trouble: we need a new reconciled namespace.
* This is expensive
*/
- ret->ns = xmlNewReconciledNs(target->doc, target, cur->ns);
+ ret->ns = xmlNewReconciledNs(target, cur->ns);
+ if (ret->ns == NULL)
+ goto error;
}
}
@@ -4000,6 +4044,8 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
xmlNodePtr tmp;
ret->children = xmlStaticCopyNodeList(cur->children, ret->doc, (xmlNodePtr) ret);
+ if (ret->children == NULL)
+ goto error;
ret->last = NULL;
tmp = ret->children;
while (tmp != NULL) {
@@ -4012,20 +4058,32 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
/*
* Try to handle IDs
*/
- if ((target!= NULL) && (cur!= NULL) &&
+ if ((target != NULL) && (cur != NULL) &&
(target->doc != NULL) && (cur->doc != NULL) &&
- (cur->doc->ids != NULL) && (cur->parent != NULL)) {
- if (xmlIsID(cur->doc, cur->parent, cur)) {
+ (cur->doc->ids != NULL) &&
+ (cur->parent != NULL) &&
+ (cur->children != NULL)) {
+ int res = xmlIsID(cur->doc, cur->parent, cur);
+
+ if (res < 0)
+ goto error;
+ if (res != 0) {
xmlChar *id;
- id = xmlNodeListGetString(cur->doc, cur->children, 1);
- if (id != NULL) {
- xmlAddID(NULL, target->doc, id, ret);
- xmlFree(id);
- }
+ id = xmlNodeGetContent((xmlNodePtr) cur);
+ if (id == NULL)
+ goto error;
+ res = xmlAddIDSafe(ret, id);
+ xmlFree(id);
+ if (res < 0)
+ goto error;
}
}
return(ret);
+
+error:
+ xmlFreeProp(ret);
+ return(NULL);
}
/**
@@ -4033,9 +4091,14 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
* @target: the element where the attribute will be grafted
* @cur: the attribute
*
- * Do a copy of the attribute.
+ * Create a copy of the attribute. This function sets the parent
+ * pointer of the copy to @target but doesn't set the attribute on
+ * the target element. Users should consider to set the attribute
+ * by calling xmlAddChild afterwards or reset the parent pointer to
+ * NULL.
*
- * Returns: a new #xmlAttrPtr, or NULL in case of error.
+ * Returns the copied attribute or NULL if a memory allocation
+ * failed.
*/
xmlAttrPtr
xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
@@ -4047,9 +4110,12 @@ xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
* @target: the element where the attributes will be grafted
* @cur: the first attribute
*
- * Do a copy of an attribute list.
+ * Create a copy of an attribute list. This function sets the
+ * parent pointers of the copied attributes to @target but doesn't
+ * set the attributes on the target element.
*
- * Returns: a new #xmlAttrPtr, or NULL in case of error.
+ * Returns the head of the copied list or NULL if a memory
+ * allocation failed.
*/
xmlAttrPtr
xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
@@ -4095,6 +4161,17 @@ xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
* namespace info, but don't recurse on children.
*/
+/**
+ * xmlStaticCopyNode:
+ * @node: source node
+ * @doc: target document
+ * @parent: target parent
+ * @extended: flags
+ *
+ * Copy a node.
+ *
+ * Returns the copy or NULL if a memory allocation failed.
+ */
xmlNodePtr
xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
int extended) {
@@ -4107,7 +4184,6 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
case XML_ELEMENT_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
case XML_XINCLUDE_START:
@@ -4123,12 +4199,7 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
#ifdef LIBXML_TREE_ENABLED
return((xmlNodePtr) xmlCopyDoc((xmlDocPtr) node, extended));
#endif /* LIBXML_TREE_ENABLED */
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
+ default:
return(NULL);
}
@@ -4136,10 +4207,8 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
* Allocate a new node and fill the fields.
*/
ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (ret == NULL) {
- xmlTreeErrMemory("copying node");
+ if (ret == NULL)
return(NULL);
- }
memset(ret, 0, sizeof(xmlNode));
ret->type = node->type;
@@ -4156,6 +4225,8 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
ret->name = xmlDictLookup(doc->dict, node->name, -1);
else
ret->name = xmlStrdup(node->name);
+ if (ret->name == NULL)
+ goto error;
}
if ((node->type != XML_ELEMENT_NODE) &&
(node->content != NULL) &&
@@ -4163,45 +4234,29 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
(node->type != XML_XINCLUDE_END) &&
(node->type != XML_XINCLUDE_START)) {
ret->content = xmlStrdup(node->content);
+ if (ret->content == NULL)
+ goto error;
}else{
if (node->type == XML_ELEMENT_NODE)
ret->line = node->line;
}
- if (parent != NULL) {
- xmlNodePtr tmp;
-
- /*
- * this is a tricky part for the node register thing:
- * in case ret does get coalesced in xmlAddChild
- * the deregister-node callback is called; so we register ret now already
- */
- if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
- xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
-
- /*
- * Note that since ret->parent is already set, xmlAddChild will
- * return early and not actually insert the node. It will only
- * coalesce text nodes and unnecessarily call xmlSetTreeDoc.
- * Assuming that the subtree to be copied always has its text
- * nodes coalesced, the somewhat confusing call to xmlAddChild
- * could be removed.
- */
- tmp = xmlAddChild(parent, ret);
- /* node could have coalesced */
- if (tmp != ret)
- return(tmp);
- }
if (!extended)
goto out;
if (((node->type == XML_ELEMENT_NODE) ||
- (node->type == XML_XINCLUDE_START)) && (node->nsDef != NULL))
+ (node->type == XML_XINCLUDE_START)) && (node->nsDef != NULL)) {
ret->nsDef = xmlCopyNamespaceList(node->nsDef);
+ if (ret->nsDef == NULL)
+ goto error;
+ }
- if (node->ns != NULL) {
- xmlNsPtr ns;
+ if ((node->type == XML_ELEMENT_NODE) && (node->ns != NULL)) {
+ xmlNsPtr ns = NULL;
+ int res;
- ns = xmlSearchNs(doc, ret, node->ns->prefix);
+ res = xmlSearchNsSafe(ret, node->ns->prefix, &ns);
+ if (res < 0)
+ goto error;
if (ns == NULL) {
/*
* Humm, we are copying an element whose namespace is defined
@@ -4211,15 +4266,19 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
* TODO: Searching the original tree seems unnecessary. We
* already have a namespace URI.
*/
- ns = xmlSearchNs(node->doc, node, node->ns->prefix);
+ res = xmlSearchNsSafe(node, node->ns->prefix, &ns);
+ if (res < 0)
+ goto error;
if (ns != NULL) {
xmlNodePtr root = ret;
while (root->parent != NULL) root = root->parent;
ret->ns = xmlNewNs(root, ns->href, ns->prefix);
} else {
- ret->ns = xmlNewReconciledNs(doc, ret, node->ns);
+ ret->ns = xmlNewReconciledNs(ret, node->ns);
}
+ if (ret->ns == NULL)
+ goto error;
} else {
/*
* reference the existing namespace definition in our own tree.
@@ -4227,9 +4286,11 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
ret->ns = ns;
}
}
- if (((node->type == XML_ELEMENT_NODE) ||
- (node->type == XML_XINCLUDE_START)) && (node->properties != NULL))
+ if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL)) {
ret->properties = xmlCopyPropList(ret, node->properties);
+ if (ret->properties == NULL)
+ goto error;
+ }
if (node->type == XML_ENTITY_REF_NODE) {
if ((doc == NULL) || (node->doc != doc)) {
/*
@@ -4250,10 +4311,8 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
insert = ret;
while (cur != NULL) {
xmlNodePtr copy = xmlStaticCopyNode(cur, doc, insert, 2);
- if (copy == NULL) {
- xmlFreeNode(ret);
- return(NULL);
- }
+ if (copy == NULL)
+ goto error;
/* Check for coalesced text nodes */
if (insert->last != copy) {
@@ -4290,13 +4349,27 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
}
out:
- /* if parent != NULL we already registered the node above */
- if ((parent == NULL) &&
- ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)))
+ if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
return(ret);
+
+error:
+ xmlFreeNode(ret);
+ return(NULL);
}
+/**
+ * xmlStaticCopyNodeList:
+ * @node: node to copy
+ * @doc: target document
+ * @parent: target node (optional)
+ *
+ * Copy a node list. If @parent is provided, sets the parent pointer
+ * of the copied nodes, but doesn't update the children and last
+ * pointer of @parent.
+ *
+ * Returns a the copy or NULL in case of error.
+ */
xmlNodePtr
xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
xmlNodePtr ret = NULL;
@@ -4305,23 +4378,44 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
int linkedSubset = 0;
while (node != NULL) {
+ xmlNodePtr next = node->next;
+
#ifdef LIBXML_TREE_ENABLED
if (node->type == XML_DTD_NODE ) {
if (doc == NULL) {
- node = node->next;
+ node = next;
continue;
}
if ((doc->intSubset == NULL) && (newSubset == NULL)) {
q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
if (q == NULL) goto error;
- q->doc = doc;
+ /* Can't fail on DTD */
+ xmlSetTreeDoc(q, doc);
q->parent = parent;
newSubset = (xmlDtdPtr) q;
- xmlAddChild(parent, q);
} else {
+ /*
+ * We don't allow multiple internal subsets in a document,
+ * so we move the DTD instead of creating a copy.
+ */
linkedSubset = 1;
q = (xmlNodePtr) doc->intSubset;
- xmlAddChild(parent, q);
+ /* Unlink */
+ if (q->prev == NULL) {
+ if (q->parent != NULL)
+ q->parent->children = q->next;
+ } else {
+ q->prev->next = q->next;
+ }
+ if (q->next == NULL) {
+ if (q->parent != NULL)
+ q->parent->last = q->prev;
+ } else {
+ q->next->prev = q->prev;
+ }
+ q->parent = parent;
+ q->next = NULL;
+ q->prev = NULL;
}
} else
#endif /* LIBXML_TREE_ENABLED */
@@ -4336,15 +4430,19 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
q->prev = p;
p = q;
}
- node = node->next;
+ node = next;
}
if ((doc != NULL) && (newSubset != NULL))
doc->intSubset = newSubset;
return(ret);
error:
- if (linkedSubset != 0)
- xmlUnlinkNode((xmlNodePtr) doc->intSubset);
xmlFreeNodeList(ret);
+ if (newSubset != NULL)
+ xmlFreeDtd(newSubset);
+ if (linkedSubset != 0) {
+ doc->intSubset->next = NULL;
+ doc->intSubset->prev = NULL;
+ }
return(NULL);
}
@@ -4355,9 +4453,11 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
* when applicable)
* if 2 copy properties and namespaces (when applicable)
*
- * Do a copy of the node.
+ * Copy a node.
*
- * Returns: a new #xmlNodePtr, or NULL in case of error.
+ * Use of this function is DISCOURAGED in favor of xmlDocCopyNode.
+ *
+ * Returns the copied node or NULL if a memory allocation failed.
*/
xmlNodePtr
xmlCopyNode(xmlNodePtr node, int extended) {
@@ -4375,9 +4475,9 @@ xmlCopyNode(xmlNodePtr node, int extended) {
* when applicable)
* if 2 copy properties and namespaces (when applicable)
*
- * Do a copy of the node to a given document.
+ * Copy a node into another document.
*
- * Returns: a new #xmlNodePtr, or NULL in case of error.
+ * Returns the copied node or NULL if a memory allocation failed.
*/
xmlNodePtr
xmlDocCopyNode(xmlNodePtr node, xmlDocPtr doc, int extended) {
@@ -4392,9 +4492,10 @@ xmlDocCopyNode(xmlNodePtr node, xmlDocPtr doc, int extended) {
* @doc: the target document
* @node: the first node in the list.
*
- * Do a recursive copy of the node list.
+ * Copy a node list and all children into a new document.
*
- * Returns: a new #xmlNodePtr, or NULL in case of error.
+ * Returns the head of the copied list or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, xmlNodePtr node) {
xmlNodePtr ret = xmlStaticCopyNodeList(node, doc, NULL);
@@ -4405,10 +4506,12 @@ xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, xmlNodePtr node) {
* xmlCopyNodeList:
* @node: the first node in the list.
*
- * Do a recursive copy of the node list.
- * Use xmlDocCopyNodeList() if possible to ensure string interning.
+ * Copy a node list and all children.
+ *
+ * Use of this function is DISCOURAGED in favor of xmlDocCopyNodeList.
*
- * Returns: a new #xmlNodePtr, or NULL in case of error.
+ * Returns the head of the copied list or NULL if a memory
+ * allocation failed.
*/
xmlNodePtr xmlCopyNodeList(xmlNodePtr node) {
xmlNodePtr ret = xmlStaticCopyNodeList(node, NULL, NULL);
@@ -4418,11 +4521,11 @@ xmlNodePtr xmlCopyNodeList(xmlNodePtr node) {
#if defined(LIBXML_TREE_ENABLED)
/**
* xmlCopyDtd:
- * @dtd: the dtd
+ * @dtd: the DTD
*
- * Do a copy of the dtd.
+ * Copy a DTD.
*
- * Returns: a new #xmlDtdPtr, or NULL in case of error.
+ * Returns the copied DTD or NULL if a memory allocation failed.
*/
xmlDtdPtr
xmlCopyDtd(xmlDtdPtr dtd) {
@@ -4432,21 +4535,36 @@ xmlCopyDtd(xmlDtdPtr dtd) {
if (dtd == NULL) return(NULL);
ret = xmlNewDtd(NULL, dtd->name, dtd->ExternalID, dtd->SystemID);
if (ret == NULL) return(NULL);
- if (dtd->entities != NULL)
+ if (dtd->entities != NULL) {
ret->entities = (void *) xmlCopyEntitiesTable(
(xmlEntitiesTablePtr) dtd->entities);
- if (dtd->notations != NULL)
+ if (ret->entities == NULL)
+ goto error;
+ }
+ if (dtd->notations != NULL) {
ret->notations = (void *) xmlCopyNotationTable(
(xmlNotationTablePtr) dtd->notations);
- if (dtd->elements != NULL)
+ if (ret->notations == NULL)
+ goto error;
+ }
+ if (dtd->elements != NULL) {
ret->elements = (void *) xmlCopyElementTable(
(xmlElementTablePtr) dtd->elements);
- if (dtd->attributes != NULL)
+ if (ret->elements == NULL)
+ goto error;
+ }
+ if (dtd->attributes != NULL) {
ret->attributes = (void *) xmlCopyAttributeTable(
(xmlAttributeTablePtr) dtd->attributes);
- if (dtd->pentities != NULL)
+ if (ret->attributes == NULL)
+ goto error;
+ }
+ if (dtd->pentities != NULL) {
ret->pentities = (void *) xmlCopyEntitiesTable(
(xmlEntitiesTablePtr) dtd->pentities);
+ if (ret->pentities == NULL)
+ goto error;
+ }
cur = dtd->children;
while (cur != NULL) {
@@ -4478,6 +4596,8 @@ xmlCopyDtd(xmlDtdPtr dtd) {
xmlGetDtdQAttrDesc(ret, tmp->elem, tmp->name, tmp->prefix);
} else if (cur->type == XML_COMMENT_NODE) {
q = xmlCopyNode(cur, 0);
+ if (q == NULL)
+ goto error;
}
if (q == NULL) {
@@ -4499,6 +4619,10 @@ xmlCopyDtd(xmlDtdPtr dtd) {
}
return(ret);
+
+error:
+ xmlFreeDtd(ret);
+ return(NULL);
}
#endif
@@ -4508,10 +4632,11 @@ xmlCopyDtd(xmlDtdPtr dtd) {
* @doc: the document
* @recursive: if not zero do a recursive copy.
*
- * Do a copy of the document info. If recursive, the content tree will
+ * Copy a document. If recursive, the content tree will
* be copied too as well as DTD, namespaces and entities.
*
- * Returns: a new #xmlDocPtr, or NULL in case of error.
+ * Returns the copied document or NULL if a memory allocation
+ * failed.
*/
xmlDocPtr
xmlCopyDoc(xmlDocPtr doc, int recursive) {
@@ -4521,12 +4646,21 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
ret = xmlNewDoc(doc->version);
if (ret == NULL) return(NULL);
ret->type = doc->type;
- if (doc->name != NULL)
+ if (doc->name != NULL) {
ret->name = xmlMemStrdup(doc->name);
- if (doc->encoding != NULL)
+ if (ret->name == NULL)
+ goto error;
+ }
+ if (doc->encoding != NULL) {
ret->encoding = xmlStrdup(doc->encoding);
- if (doc->URL != NULL)
+ if (ret->encoding == NULL)
+ goto error;
+ }
+ if (doc->URL != NULL) {
ret->URL = xmlStrdup(doc->URL);
+ if (ret->URL == NULL)
+ goto error;
+ }
ret->charset = doc->charset;
ret->compression = doc->compression;
ret->standalone = doc->standalone;
@@ -4537,21 +4671,24 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
#ifdef LIBXML_TREE_ENABLED
if (doc->intSubset != NULL) {
ret->intSubset = xmlCopyDtd(doc->intSubset);
- if (ret->intSubset == NULL) {
- xmlFreeDoc(ret);
- return(NULL);
- }
+ if (ret->intSubset == NULL)
+ goto error;
+ /* Can't fail on DTD */
xmlSetTreeDoc((xmlNodePtr)ret->intSubset, ret);
- ret->intSubset->parent = ret;
}
#endif
- if (doc->oldNs != NULL)
+ if (doc->oldNs != NULL) {
ret->oldNs = xmlCopyNamespaceList(doc->oldNs);
+ if (ret->oldNs == NULL)
+ goto error;
+ }
if (doc->children != NULL) {
xmlNodePtr tmp;
ret->children = xmlStaticCopyNodeList(doc->children, ret,
(xmlNodePtr)ret);
+ if (ret->children == NULL)
+ goto error;
ret->last = NULL;
tmp = ret->children;
while (tmp != NULL) {
@@ -4561,6 +4698,10 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
}
}
return(ret);
+
+error:
+ xmlFreeDoc(ret);
+ return(NULL);
}
#endif /* LIBXML_TREE_ENABLED */
@@ -4663,13 +4804,10 @@ xmlGetNodePath(const xmlNode *node)
buf_len = 500;
buffer = (xmlChar *) xmlMallocAtomic(buf_len);
- if (buffer == NULL) {
- xmlTreeErrMemory("getting node path");
+ if (buffer == NULL)
return (NULL);
- }
buf = (xmlChar *) xmlMallocAtomic(buf_len);
if (buf == NULL) {
- xmlTreeErrMemory("getting node path");
xmlFree(buffer);
return (NULL);
}
@@ -4856,7 +4994,6 @@ xmlGetNodePath(const xmlNode *node)
2 * buf_len + xmlStrlen(buffer) + sizeof(nametemp) + 20;
temp = (xmlChar *) xmlRealloc(buffer, buf_len);
if (temp == NULL) {
- xmlTreeErrMemory("getting node path");
xmlFree(buf);
xmlFree(buffer);
return (NULL);
@@ -4864,7 +5001,6 @@ xmlGetNodePath(const xmlNode *node)
buffer = temp;
temp = (xmlChar *) xmlRealloc(buf, buf_len);
if (temp == NULL) {
- xmlTreeErrMemory("getting node path");
xmlFree(buf);
xmlFree(buffer);
return (NULL);
@@ -4892,7 +5028,7 @@ xmlGetNodePath(const xmlNode *node)
* Get the root element of the document (doc->children is a list
* containing possibly comments, PIs, etc ...).
*
- * Returns the #xmlNodePtr for the root or NULL
+ * Returns the root element or NULL if no element was found.
*/
xmlNodePtr
xmlDocGetRootElement(const xmlDoc *doc) {
@@ -4918,7 +5054,10 @@ xmlDocGetRootElement(const xmlDoc *doc) {
* Set the root element of the document (doc->children is a list
* containing possibly comments, PIs, etc ...).
*
- * Returns the old root element if any was found, NULL if root was NULL
+ * @root must be an element node. It is unlinked before insertion.
+ *
+ * Returns the unlinked old root element or NULL if the document
+ * didn't have a root element or a memory allocation failed.
*/
xmlNodePtr
xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
@@ -4927,15 +5066,18 @@ xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
if (doc == NULL) return(NULL);
if ((root == NULL) || (root->type == XML_NAMESPACE_DECL))
return(NULL);
- xmlUnlinkNode(root);
- xmlSetTreeDoc(root, doc);
- root->parent = (xmlNodePtr) doc;
old = doc->children;
while (old != NULL) {
if (old->type == XML_ELEMENT_NODE)
break;
old = old->next;
}
+ if (old == root)
+ return(old);
+ xmlUnlinkNodeInternal(root);
+ if (xmlSetTreeDoc(root, doc) < 0)
+ return(NULL);
+ root->parent = (xmlNodePtr) doc;
if (old == NULL) {
if (doc->children == NULL) {
doc->children = root;
@@ -4958,40 +5100,27 @@ xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
*
* Set the language of a node, i.e. the values of the xml:lang
* attribute.
+ *
+ * Return 0 on success, 1 if arguments are invalid, -1 if a
+ * memory allocation failed.
*/
-void
+int
xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
xmlNsPtr ns;
+ xmlAttrPtr attr;
+ int res;
- if (cur == NULL) return;
- switch(cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_PI_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return;
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- break;
- }
- ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
- if (ns == NULL)
- return;
- xmlSetNsProp(cur, ns, BAD_CAST "lang", lang);
+ if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
+ return(1);
+
+ res = xmlSearchNsByHrefSafe(cur, XML_XML_NAMESPACE, &ns);
+ if (res != 0)
+ return(res);
+ attr = xmlSetNsProp(cur, ns, BAD_CAST "lang", lang);
+ if (attr == NULL)
+ return(-1);
+
+ return(0);
}
#endif /* LIBXML_TREE_ENABLED */
@@ -5008,15 +5137,22 @@ xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
xmlChar *
xmlNodeGetLang(const xmlNode *cur) {
xmlChar *lang;
+ int res;
if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
return(NULL);
+
while (cur != NULL) {
- lang = xmlGetNsProp(cur, BAD_CAST "lang", XML_XML_NAMESPACE);
+ res = xmlNodeGetAttrValue(cur, BAD_CAST "lang", XML_XML_NAMESPACE,
+ &lang);
+ if (res < 0)
+ return(NULL);
if (lang != NULL)
return(lang);
+
cur = cur->parent;
}
+
return(NULL);
}
@@ -5029,47 +5165,34 @@ xmlNodeGetLang(const xmlNode *cur) {
*
* Set (or reset) the space preserving behaviour of a node, i.e. the
* value of the xml:space attribute.
+ *
+ * Return 0 on success, 1 if arguments are invalid, -1 if a
+ * memory allocation failed.
*/
-void
+int
xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
xmlNsPtr ns;
+ xmlAttrPtr attr;
+ const char *string;
+ int res;
- if (cur == NULL) return;
- switch(cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_PI_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return;
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- break;
- }
- ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
- if (ns == NULL)
- return;
- switch (val) {
- case 0:
- xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "default");
- break;
- case 1:
- xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "preserve");
- break;
- }
+ if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
+ return(1);
+
+ res = xmlSearchNsByHrefSafe(cur, XML_XML_NAMESPACE, &ns);
+ if (res != 0)
+ return(res);
+
+ if (val == 0)
+ string = "default";
+ else
+ string = "preserve";
+
+ attr = xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST string);
+ if (attr == NULL)
+ return(-1);
+
+ return(0);
}
#endif /* LIBXML_TREE_ENABLED */
@@ -5086,11 +5209,16 @@ xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
int
xmlNodeGetSpacePreserve(const xmlNode *cur) {
xmlChar *space;
+ int res;
if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
return(-1);
+
while (cur != NULL) {
- space = xmlGetNsProp(cur, BAD_CAST "space", XML_XML_NAMESPACE);
+ res = xmlNodeGetAttrValue(cur, BAD_CAST "space", XML_XML_NAMESPACE,
+ &space);
+ if (res < 0)
+ return(-1);
if (space != NULL) {
if (xmlStrEqual(space, BAD_CAST "preserve")) {
xmlFree(space);
@@ -5102,8 +5230,10 @@ xmlNodeGetSpacePreserve(const xmlNode *cur) {
}
xmlFree(space);
}
+
cur = cur->parent;
}
+
return(-1);
}
@@ -5119,51 +5249,39 @@ void
xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
xmlDocPtr doc;
xmlDictPtr dict;
- const xmlChar *freeme = NULL;
+ const xmlChar *copy;
+ const xmlChar *oldName;
if (cur == NULL) return;
if (name == NULL) return;
switch(cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return;
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
case XML_PI_NODE:
case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_DTD_NODE:
- case XML_DOCUMENT_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
break;
+ default:
+ return;
}
+
doc = cur->doc;
if (doc != NULL)
dict = doc->dict;
else
dict = NULL;
- if (dict != NULL) {
- if ((cur->name != NULL) && (!xmlDictOwns(dict, cur->name)))
- freeme = cur->name;
- cur->name = xmlDictLookup(dict, name, -1);
- } else {
- if (cur->name != NULL)
- freeme = cur->name;
- cur->name = xmlStrdup(name);
- }
- if (freeme)
- xmlFree((xmlChar *) freeme);
+ if (dict != NULL)
+ copy = xmlDictLookup(dict, name, -1);
+ else
+ copy = xmlStrdup(name);
+ if (copy == NULL)
+ return;
+
+ oldName = cur->name;
+ cur->name = copy;
+ if ((oldName != NULL) &&
+ ((dict == NULL) || (!xmlDictOwns(dict, oldName))))
+ xmlFree((xmlChar *) oldName);
}
#endif
@@ -5175,31 +5293,17 @@ xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
*
* Set (or reset) the base URI of a node, i.e. the value of the
* xml:base attribute.
+ *
+ * Returns 0 on success, -1 on error.
*/
-void
+int
xmlNodeSetBase(xmlNodePtr cur, const xmlChar* uri) {
xmlNsPtr ns;
xmlChar* fixed;
- if (cur == NULL) return;
+ if (cur == NULL)
+ return(-1);
switch(cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_PI_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return;
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
break;
@@ -5209,31 +5313,40 @@ xmlNodeSetBase(xmlNodePtr cur, const xmlChar* uri) {
if (doc->URL != NULL)
xmlFree((xmlChar *) doc->URL);
- if (uri == NULL)
+ if (uri == NULL) {
doc->URL = NULL;
- else
+ } else {
doc->URL = xmlPathToURI(uri);
- return;
+ if (doc->URL == NULL)
+ return(-1);
+ }
+ return(0);
}
+ default:
+ return(-1);
}
- ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
+ xmlSearchNsByHrefSafe(cur, XML_XML_NAMESPACE, &ns);
if (ns == NULL)
- return;
+ return(-1);
fixed = xmlPathToURI(uri);
- if (fixed != NULL) {
- xmlSetNsProp(cur, ns, BAD_CAST "base", fixed);
- xmlFree(fixed);
- } else {
- xmlSetNsProp(cur, ns, BAD_CAST "base", uri);
+ if (fixed == NULL)
+ return(-1);
+ if (xmlSetNsProp(cur, ns, BAD_CAST "base", fixed) == NULL) {
+ xmlFree(fixed);
+ return(-1);
}
+ xmlFree(fixed);
+
+ return(0);
}
#endif /* LIBXML_TREE_ENABLED */
/**
- * xmlNodeGetBase:
+ * xmlNodeGetBaseSafe:
* @doc: the document the node pertains to
* @cur: the node being checked
+ * @baseOut: pointer to base
*
* Searches for the BASE URL. The code should work on both XML
* and HTML document even if base mechanisms are completely different.
@@ -5244,19 +5357,27 @@ xmlNodeSetBase(xmlNodePtr cur, const xmlChar* uri) {
* However it does not return the document base (5.1.3), use
* doc->URL in this case
*
- * Returns a pointer to the base URL, or NULL if not found
- * It's up to the caller to free the memory with xmlFree().
+ * Available since 2.13.0.
+ *
+ * Return 0 in case of success, 1 if a URI or argument is invalid, -1 if a
+ * memory allocation failed.
*/
-xmlChar *
-xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur) {
- xmlChar *oldbase = NULL;
+int
+xmlNodeGetBaseSafe(const xmlDoc *doc, const xmlNode *cur, xmlChar **baseOut) {
+ xmlChar *ret = NULL;
xmlChar *base, *newbase;
+ int res;
+ if (baseOut == NULL)
+ return(1);
+ *baseOut = NULL;
if ((cur == NULL) && (doc == NULL))
- return(NULL);
+ return(1);
if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL))
- return(NULL);
- if (doc == NULL) doc = cur->doc;
+ return(1);
+ if (doc == NULL)
+ doc = cur->doc;
+
if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
cur = doc->children;
while ((cur != NULL) && (cur->name != NULL)) {
@@ -5273,50 +5394,91 @@ xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur) {
continue;
}
if (!xmlStrcasecmp(cur->name, BAD_CAST "base")) {
- return(xmlGetProp(cur, BAD_CAST "href"));
+ if (xmlNodeGetAttrValue(cur, BAD_CAST "href", NULL, &ret) < 0)
+ return(-1);
+ if (ret == NULL)
+ return(1);
+ goto found;
}
cur = cur->next;
}
- return(NULL);
+ return(0);
}
+
while (cur != NULL) {
if (cur->type == XML_ENTITY_DECL) {
xmlEntityPtr ent = (xmlEntityPtr) cur;
- return(xmlStrdup(ent->URI));
+
+ if (ent->URI == NULL)
+ break;
+ xmlFree(ret);
+ ret = xmlStrdup(ent->URI);
+ if (ret == NULL)
+ return(-1);
+ goto found;
}
if (cur->type == XML_ELEMENT_NODE) {
- base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
+ if (xmlNodeGetAttrValue(cur, BAD_CAST "base", XML_XML_NAMESPACE,
+ &base) < 0) {
+ xmlFree(ret);
+ return(-1);
+ }
if (base != NULL) {
- if (oldbase != NULL) {
- newbase = xmlBuildURI(oldbase, base);
- if (newbase != NULL) {
- xmlFree(oldbase);
- xmlFree(base);
- oldbase = newbase;
- } else {
- xmlFree(oldbase);
- xmlFree(base);
- return(NULL);
- }
+ if (ret != NULL) {
+ res = xmlBuildURISafe(ret, base, &newbase);
+ xmlFree(ret);
+ xmlFree(base);
+ if (res != 0)
+ return(res);
+ ret = newbase;
} else {
- oldbase = base;
+ ret = base;
}
- if ((!xmlStrncmp(oldbase, BAD_CAST "http://", 7)) ||
- (!xmlStrncmp(oldbase, BAD_CAST "ftp://", 6)) ||
- (!xmlStrncmp(oldbase, BAD_CAST "urn:", 4)))
- return(oldbase);
+ if ((!xmlStrncmp(ret, BAD_CAST "http://", 7)) ||
+ (!xmlStrncmp(ret, BAD_CAST "ftp://", 6)) ||
+ (!xmlStrncmp(ret, BAD_CAST "urn:", 4)))
+ goto found;
}
}
cur = cur->parent;
}
+
if ((doc != NULL) && (doc->URL != NULL)) {
- if (oldbase == NULL)
- return(xmlStrdup(doc->URL));
- newbase = xmlBuildURI(oldbase, doc->URL);
- xmlFree(oldbase);
- return(newbase);
+ if (ret == NULL) {
+ ret = xmlStrdup(doc->URL);
+ if (ret == NULL)
+ return(-1);
+ } else {
+ res = xmlBuildURISafe(ret, doc->URL, &newbase);
+ xmlFree(ret);
+ if (res != 0)
+ return(res);
+ ret = newbase;
+ }
}
- return(oldbase);
+
+found:
+ *baseOut = ret;
+ return(0);
+}
+
+/**
+ * xmlNodeGetBase:
+ * @doc: the document the node pertains to
+ * @cur: the node being checked
+ *
+ * See xmlNodeGetBaseSafe. This function doesn't allow to distinguish
+ * memory allocation failures from a non-existing base.
+ *
+ * Returns a pointer to the base URL, or NULL if not found
+ * It's up to the caller to free the memory with xmlFree().
+ */
+xmlChar *
+xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur) {
+ xmlChar *base;
+
+ xmlNodeGetBaseSafe(doc, cur, &base);
+ return(base);
}
/**
@@ -5347,6 +5509,69 @@ xmlNodeBufGetContent(xmlBufferPtr buffer, const xmlNode *cur)
return(0);
}
+static void
+xmlBufGetEntityRefContent(xmlBufPtr buf, const xmlNode *ref) {
+ xmlEntityPtr ent;
+
+ if (ref->children != NULL) {
+ ent = (xmlEntityPtr) ref->children;
+ } else {
+ /* lookup entity declaration */
+ ent = xmlGetDocEntity(ref->doc, ref->name);
+ if (ent == NULL)
+ return;
+ }
+
+ /*
+ * The parser should always expand predefined entities but it's
+ * possible to create references to predefined entities using
+ * the tree API.
+ */
+ if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
+ xmlBufCat(buf, ent->content);
+ return;
+ }
+
+ if (ent->flags & XML_ENT_EXPANDING)
+ return;
+
+ ent->flags |= XML_ENT_EXPANDING;
+ xmlBufGetChildContent(buf, (xmlNodePtr) ent);
+ ent->flags &= ~XML_ENT_EXPANDING;
+}
+
+static void
+xmlBufGetChildContent(xmlBufPtr buf, const xmlNode *tree) {
+ const xmlNode *cur = tree->children;
+
+ while (cur != NULL) {
+ switch (cur->type) {
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ xmlBufCat(buf, cur->content);
+ break;
+
+ case XML_ENTITY_REF_NODE:
+ xmlBufGetEntityRefContent(buf, cur);
+ break;
+
+ default:
+ if (cur->children != NULL) {
+ cur = cur->children;
+ continue;
+ }
+ break;
+ }
+
+ while (cur->next == NULL) {
+ cur = cur->parent;
+ if (cur == tree)
+ return;
+ }
+ cur = cur->next;
+ }
+}
+
/**
* xmlBufGetNodeContent:
* @buf: a buffer xmlBufPtr
@@ -5363,127 +5588,38 @@ xmlNodeBufGetContent(xmlBufferPtr buffer, const xmlNode *cur)
int
xmlBufGetNodeContent(xmlBufPtr buf, const xmlNode *cur)
{
- if ((cur == NULL) || (buf == NULL)) return(-1);
+ if ((cur == NULL) || (buf == NULL))
+ return(-1);
+
switch (cur->type) {
- case XML_CDATA_SECTION_NODE:
- case XML_TEXT_NODE:
- xmlBufCat(buf, cur->content);
- break;
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
case XML_DOCUMENT_FRAG_NODE:
- case XML_ELEMENT_NODE:{
- const xmlNode *tmp = cur;
-
- while (tmp != NULL) {
- switch (tmp->type) {
- case XML_CDATA_SECTION_NODE:
- case XML_TEXT_NODE:
- if (tmp->content != NULL)
- xmlBufCat(buf, tmp->content);
- break;
- case XML_ENTITY_REF_NODE:
- xmlBufGetNodeContent(buf, tmp);
- break;
- default:
- break;
- }
- /*
- * Skip to next node
- */
- if (tmp->children != NULL) {
- if (tmp->children->type != XML_ENTITY_DECL) {
- tmp = tmp->children;
- continue;
- }
- }
- if (tmp == cur)
- break;
-
- if (tmp->next != NULL) {
- tmp = tmp->next;
- continue;
- }
-
- do {
- tmp = tmp->parent;
- if (tmp == NULL)
- break;
- if (tmp == cur) {
- tmp = NULL;
- break;
- }
- if (tmp->next != NULL) {
- tmp = tmp->next;
- break;
- }
- } while (tmp != NULL);
- }
- break;
- }
- case XML_ATTRIBUTE_NODE:{
- xmlAttrPtr attr = (xmlAttrPtr) cur;
- xmlNodePtr tmp = attr->children;
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ case XML_ENTITY_DECL:
+ xmlBufGetChildContent(buf, cur);
+ break;
- while (tmp != NULL) {
- if (tmp->type == XML_TEXT_NODE)
- xmlBufCat(buf, tmp->content);
- else
- xmlBufGetNodeContent(buf, tmp);
- tmp = tmp->next;
- }
- break;
- }
+ case XML_CDATA_SECTION_NODE:
+ case XML_TEXT_NODE:
case XML_COMMENT_NODE:
case XML_PI_NODE:
xmlBufCat(buf, cur->content);
break;
- case XML_ENTITY_REF_NODE:{
- xmlEntityPtr ent;
- xmlNodePtr tmp;
-
- /* lookup entity declaration */
- ent = xmlGetDocEntity(cur->doc, cur->name);
- if (ent == NULL)
- return(-1);
- /* an entity content can be any "well balanced chunk",
- * i.e. the result of the content [43] production:
- * http://www.w3.org/TR/REC-xml#NT-content
- * -> we iterate through child nodes and recursive call
- * xmlNodeGetContent() which handles all possible node types */
- tmp = ent->children;
- while (tmp) {
- xmlBufGetNodeContent(buf, tmp);
- tmp = tmp->next;
- }
- break;
- }
- case XML_ENTITY_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
+ case XML_ENTITY_REF_NODE:
+ xmlBufGetEntityRefContent(buf, cur);
break;
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
- cur = cur->children;
- while (cur!= NULL) {
- if ((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_TEXT_NODE) ||
- (cur->type == XML_CDATA_SECTION_NODE)) {
- xmlBufGetNodeContent(buf, cur);
- }
- cur = cur->next;
- }
- break;
+
case XML_NAMESPACE_DECL:
xmlBufCat(buf, ((xmlNsPtr) cur)->href);
break;
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
+
+ default:
break;
}
+
return(0);
}
@@ -5501,163 +5637,131 @@ xmlBufGetNodeContent(xmlBufPtr buf, const xmlNode *cur)
xmlChar *
xmlNodeGetContent(const xmlNode *cur)
{
+ xmlBufPtr buf;
+ xmlChar *ret;
+
if (cur == NULL)
return (NULL);
+
switch (cur->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_ENTITY_REF_NODE:
+ break;
+
case XML_DOCUMENT_FRAG_NODE:
- case XML_ELEMENT_NODE:{
- xmlBufPtr buf;
- xmlChar *ret;
-
- buf = xmlBufCreateSize(64);
- if (buf == NULL)
- return (NULL);
- xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
- xmlBufGetNodeContent(buf, cur);
- ret = xmlBufDetach(buf);
- xmlBufFree(buf);
- return (ret);
- }
+ case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
- return(xmlGetPropNodeValueInternal((xmlAttrPtr) cur));
- case XML_COMMENT_NODE:
- case XML_PI_NODE:
- if (cur->content != NULL)
- return (xmlStrdup(cur->content));
- return (NULL);
- case XML_ENTITY_REF_NODE:{
- xmlEntityPtr ent;
- xmlBufPtr buf;
- xmlChar *ret;
-
- /* lookup entity declaration */
- ent = xmlGetDocEntity(cur->doc, cur->name);
- if (ent == NULL)
- return (NULL);
-
- buf = xmlBufCreate();
- if (buf == NULL)
- return (NULL);
- xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
-
- xmlBufGetNodeContent(buf, cur);
-
- ret = xmlBufDetach(buf);
- xmlBufFree(buf);
- return (ret);
+ case XML_ENTITY_DECL: {
+ xmlNodePtr children = cur->children;
+
+ if (children == NULL)
+ return(xmlStrdup(BAD_CAST ""));
+
+ /* Optimization for single text children */
+ if (((children->type == XML_TEXT_NODE) ||
+ (children->type == XML_CDATA_SECTION_NODE)) &&
+ (children->next == NULL)) {
+ if (children->content == NULL)
+ return(xmlStrdup(BAD_CAST ""));
+ return(xmlStrdup(children->content));
}
- case XML_ENTITY_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return (NULL);
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE: {
- xmlBufPtr buf;
- xmlChar *ret;
-
- buf = xmlBufCreate();
- if (buf == NULL)
- return (NULL);
- xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
- xmlBufGetNodeContent(buf, (xmlNodePtr) cur);
-
- ret = xmlBufDetach(buf);
- xmlBufFree(buf);
- return (ret);
- }
- case XML_NAMESPACE_DECL: {
- xmlChar *tmp;
+ break;
+ }
- tmp = xmlStrdup(((xmlNsPtr) cur)->href);
- return (tmp);
- }
- case XML_ELEMENT_DECL:
- /* TODO !!! */
- return (NULL);
- case XML_ATTRIBUTE_DECL:
- /* TODO !!! */
- return (NULL);
- case XML_ENTITY_DECL:
- /* TODO !!! */
- return (NULL);
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
+ case XML_COMMENT_NODE:
+ case XML_PI_NODE:
if (cur->content != NULL)
- return (xmlStrdup(cur->content));
- return (NULL);
+ return(xmlStrdup(cur->content));
+ else
+ return(xmlStrdup(BAD_CAST ""));
+
+ case XML_NAMESPACE_DECL:
+ return(xmlStrdup(((xmlNsPtr) cur)->href));
+
+ default:
+ return(NULL);
}
- return (NULL);
+
+ buf = xmlBufCreateSize(64);
+ if (buf == NULL)
+ return (NULL);
+ xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
+ xmlBufGetNodeContent(buf, cur);
+ ret = xmlBufDetach(buf);
+ xmlBufFree(buf);
+
+ return(ret);
}
-/**
- * xmlNodeSetContent:
- * @cur: the node being modified
- * @content: the new value of the content
- *
- * Replace the content of a node.
- * NOTE: @content is supposed to be a piece of XML CDATA, so it allows entity
- * references, but XML special chars need to be escaped first by using
- * xmlEncodeEntitiesReentrant() resp. xmlEncodeSpecialChars().
- */
-void
-xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
+static int
+xmlNodeSetContentInternal(xmlNodePtr cur, const xmlChar *content, int len) {
if (cur == NULL) {
- return;
+ return(1);
}
switch (cur->type) {
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
- cur->children = xmlStringGetNodeList(cur->doc, content);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
+ if (xmlNodeParseContent(cur, content, len) < 0)
+ return(-1);
break;
+
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
case XML_PI_NODE:
- case XML_COMMENT_NODE:
- if ((cur->content != NULL) &&
- (cur->content != (xmlChar *) &(cur->properties))) {
- if (!((cur->doc != NULL) && (cur->doc->dict != NULL) &&
- (xmlDictOwns(cur->doc->dict, cur->content))))
- xmlFree(cur->content);
- }
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
- cur->last = cur->children = NULL;
+ case XML_COMMENT_NODE: {
+ xmlChar *copy = NULL;
+
if (content != NULL) {
- cur->content = xmlStrdup(content);
- } else
- cur->content = NULL;
- cur->properties = NULL;
- break;
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- break;
- case XML_NOTATION_NODE:
- break;
- case XML_DTD_NODE:
- break;
- case XML_NAMESPACE_DECL:
- break;
- case XML_ELEMENT_DECL:
- /* TODO !!! */
- break;
- case XML_ATTRIBUTE_DECL:
- /* TODO !!! */
- break;
- case XML_ENTITY_DECL:
- /* TODO !!! */
+ if (len < 0)
+ copy = xmlStrdup(content);
+ else
+ copy = xmlStrndup(content, len);
+ if (copy == NULL)
+ return(-1);
+ }
+
+ xmlTextSetContent(cur, copy);
break;
+ }
+
+ default:
+ break;
}
+
+ return(0);
+}
+
+/**
+ * xmlNodeSetContent:
+ * @cur: the node being modified
+ * @content: the new value of the content
+ *
+ * Replace the text content of a node.
+ *
+ * Sets the raw text content of text, CDATA, comment or PI nodes.
+ *
+ * For element and attribute nodes, removes all children and
+ * replaces them by parsing @content which is expected to be a
+ * valid XML attribute value possibly containing character and
+ * entity references. Syntax errors and references to undeclared
+ * entities are ignored silently. Unfortunately, there isn't an
+ * API to pass raw content directly. An inefficient work-around
+ * is to escape the content with xmlEncodeSpecialChars before
+ * passing it. A better trick is clearing the old content
+ * with xmlNodeSetContent(node, NULL) first and then calling
+ * xmlNodeAddContent(node, content). Unlike this function,
+ * xmlNodeAddContent accepts raw text.
+ *
+ * Returns 0 on success, 1 on error, -1 if a memory allocation failed.
+ */
+int
+xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
+ return(xmlNodeSetContentInternal(cur, content, -1));
}
#ifdef LIBXML_TREE_ENABLED
@@ -5667,63 +5771,13 @@ xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
* @content: the new value of the content
* @len: the size of @content
*
- * Replace the content of a node.
- * NOTE: @content is supposed to be a piece of XML CDATA, so it allows entity
- * references, but XML special chars need to be escaped first by using
- * xmlEncodeEntitiesReentrant() resp. xmlEncodeSpecialChars().
+ * See xmlNodeSetContent.
+ *
+ * Returns 0 on success, 1 on error, -1 if a memory allocation failed.
*/
-void
+int
xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
- if (cur == NULL) {
- return;
- }
- switch (cur->type) {
- case XML_DOCUMENT_FRAG_NODE:
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
- cur->children = xmlStringLenGetNodeList(cur->doc, content, len);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
- break;
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_NOTATION_NODE:
- if ((cur->content != NULL) &&
- (cur->content != (xmlChar *) &(cur->properties))) {
- if (!((cur->doc != NULL) && (cur->doc->dict != NULL) &&
- (xmlDictOwns(cur->doc->dict, cur->content))))
- xmlFree(cur->content);
- }
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
- cur->children = cur->last = NULL;
- if (content != NULL) {
- cur->content = xmlStrndup(content, len);
- } else
- cur->content = NULL;
- cur->properties = NULL;
- break;
- case XML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- break;
- case XML_ELEMENT_DECL:
- /* TODO !!! */
- break;
- case XML_ATTRIBUTE_DECL:
- /* TODO !!! */
- break;
- case XML_ENTITY_DECL:
- /* TODO !!! */
- break;
- }
+ return(xmlNodeSetContentInternal(cur, content, len));
}
#endif /* LIBXML_TREE_ENABLED */
@@ -5737,63 +5791,43 @@ xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
* NOTE: In contrast to xmlNodeSetContentLen(), @content is supposed to be
* raw text, so unescaped XML special chars are allowed, entity
* references are not supported.
+ *
+ * Returns 0 on success, 1 on error, -1 if a memory allocation failed.
*/
-void
+int
xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
- if (cur == NULL) {
- return;
- }
- if (len <= 0) return;
+ if (cur == NULL)
+ return(1);
+ if ((content == NULL) || (len <= 0))
+ return(0);
+
switch (cur->type) {
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE: {
- xmlNodePtr last, newNode, tmp;
+ xmlNodePtr newNode, tmp;
- last = cur->last;
newNode = xmlNewDocTextLen(cur->doc, content, len);
- if (newNode != NULL) {
- tmp = xmlAddChild(cur, newNode);
- if (tmp != newNode)
- return;
- if ((last != NULL) && (last->next == newNode)) {
- xmlTextMerge(last, newNode);
- }
- }
+ if (newNode == NULL)
+ return(-1);
+ tmp = xmlAddChild(cur, newNode);
+ if (tmp == NULL) {
+ xmlFreeNode(newNode);
+ return(-1);
+ }
break;
}
case XML_ATTRIBUTE_NODE:
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_NOTATION_NODE:
- if (content != NULL) {
- if ((cur->content == (xmlChar *) &(cur->properties)) ||
- ((cur->doc != NULL) && (cur->doc->dict != NULL) &&
- xmlDictOwns(cur->doc->dict, cur->content))) {
- cur->content = xmlStrncatNew(cur->content, content, len);
- cur->properties = NULL;
- } else {
- cur->content = xmlStrncat(cur->content, content, len);
- }
- }
- break;
- case XML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- break;
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- break;
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ return(xmlTextAddContent(cur, content, len));
+ default:
+ break;
}
+
+ return(0);
}
/**
@@ -5805,17 +5839,12 @@ xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
* NOTE: In contrast to xmlNodeSetContent(), @content is supposed to be
* raw text, so unescaped XML special chars are allowed, entity
* references are not supported.
+ *
+ * Returns 0 on success, 1 on error, -1 if a memory allocation failed.
*/
-void
+int
xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content) {
- int len;
-
- if (cur == NULL) {
- return;
- }
- if (content == NULL) return;
- len = xmlStrlen(content);
- xmlNodeAddContentLen(cur, content, len);
+ return(xmlNodeAddContentLen(cur, content, xmlStrlen(content)));
}
/**
@@ -5823,53 +5852,66 @@ xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content) {
* @first: the first text node
* @second: the second text node being merged
*
- * Merge two text nodes into one
- * Returns the first text node augmented
+ * Merge the second text node into the first. The second node is
+ * unlinked and freed.
+ *
+ * Returns the first text node augmented or NULL in case of error.
*/
xmlNodePtr
xmlTextMerge(xmlNodePtr first, xmlNodePtr second) {
- if (first == NULL) return(second);
- if (second == NULL) return(first);
- if (first->type != XML_TEXT_NODE) return(first);
- if (second->type != XML_TEXT_NODE) return(first);
- if (second->name != first->name)
- return(first);
- xmlNodeAddContent(first, second->content);
- xmlUnlinkNode(second);
+ if ((first == NULL) || (first->type != XML_TEXT_NODE) ||
+ (second == NULL) || (second->type != XML_TEXT_NODE) ||
+ (first == second) ||
+ (first->name != second->name))
+ return(NULL);
+
+ if (xmlTextAddContent(first, second->content, -1) < 0)
+ return(NULL);
+
+ xmlUnlinkNodeInternal(second);
xmlFreeNode(second);
return(first);
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
/**
- * xmlGetNsList:
+ * xmlGetNsListSafe:
* @doc: the document
* @node: the current node
+ * @out: the returned namespace array
+ *
+ * Find all in-scope namespaces of a node. @out returns a NULL
+ * terminated array of namespace pointers that must be freed by
+ * the caller.
*
- * Search all the namespace applying to a given element.
- * Returns an NULL terminated array of all the #xmlNsPtr found
- * that need to be freed by the caller or NULL if no
- * namespace if defined
+ * Available since 2.13.0.
+ *
+ * Returns 0 on success, 1 if no namespaces were found, -1 if a
+ * memory allocation failed.
*/
-xmlNsPtr *
-xmlGetNsList(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node)
+int
+xmlGetNsListSafe(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node,
+ xmlNsPtr **out)
{
xmlNsPtr cur;
- xmlNsPtr *ret = NULL;
+ xmlNsPtr *namespaces = NULL;
int nbns = 0;
int maxns = 0;
int i;
+ if (out == NULL)
+ return(1);
+ *out = NULL;
if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
- return(NULL);
+ return(1);
while (node != NULL) {
if (node->type == XML_ELEMENT_NODE) {
cur = node->nsDef;
while (cur != NULL) {
for (i = 0; i < nbns; i++) {
- if ((cur->prefix == ret[i]->prefix) ||
- (xmlStrEqual(cur->prefix, ret[i]->prefix)))
+ if ((cur->prefix == namespaces[i]->prefix) ||
+ (xmlStrEqual(cur->prefix, namespaces[i]->prefix)))
break;
}
if (i >= nbns) {
@@ -5877,18 +5919,17 @@ xmlGetNsList(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node)
xmlNsPtr *tmp;
maxns = maxns ? maxns * 2 : 10;
- tmp = (xmlNsPtr *) xmlRealloc(ret,
+ tmp = (xmlNsPtr *) xmlRealloc(namespaces,
(maxns + 1) *
sizeof(xmlNsPtr));
if (tmp == NULL) {
- xmlTreeErrMemory("getting namespace list");
- xmlFree(ret);
- return (NULL);
+ xmlFree(namespaces);
+ return(-1);
}
- ret = tmp;
+ namespaces = tmp;
}
- ret[nbns++] = cur;
- ret[nbns] = NULL;
+ namespaces[nbns++] = cur;
+ namespaces[nbns] = NULL;
}
cur = cur->next;
@@ -5896,40 +5937,161 @@ xmlGetNsList(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node)
}
node = node->parent;
}
- return (ret);
+
+ *out = namespaces;
+ return((namespaces == NULL) ? 1 : 0);
+}
+
+/**
+ * xmlGetNsList:
+ * @doc: the document
+ * @node: the current node
+ *
+ * Find all in-scope namespaces of a node.
+ *
+ * Use xmlGetNsListSafe for better error reporting.
+ *
+ * Returns a NULL terminated array of namespace pointers that must
+ * be freed by the caller or NULL if no namespaces were found or
+ * a memory allocation failed.
+ */
+xmlNsPtr *
+xmlGetNsList(const xmlDoc *doc, const xmlNode *node)
+{
+ xmlNsPtr *ret;
+
+ xmlGetNsListSafe(doc, node, &ret);
+ return(ret);
}
#endif /* LIBXML_TREE_ENABLED */
+static xmlNsPtr
+xmlNewXmlNs(void) {
+ xmlNsPtr ns;
+
+ ns = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
+ if (ns == NULL)
+ return(NULL);
+ memset(ns, 0, sizeof(xmlNs));
+ ns->type = XML_LOCAL_NAMESPACE;
+ ns->href = xmlStrdup(XML_XML_NAMESPACE);
+ if (ns->href == NULL) {
+ xmlFreeNs(ns);
+ return(NULL);
+ }
+ ns->prefix = xmlStrdup(BAD_CAST "xml");
+ if (ns->prefix == NULL) {
+ xmlFreeNs(ns);
+ return(NULL);
+ }
+
+ return(ns);
+}
+
/*
* xmlTreeEnsureXMLDecl:
* @doc: the doc
*
* Ensures that there is an XML namespace declaration on the doc.
*
-* Returns the XML ns-struct or NULL on API and internal errors.
+* Returns the XML ns-struct or NULL if a memory allocation failed.
*/
static xmlNsPtr
xmlTreeEnsureXMLDecl(xmlDocPtr doc)
{
- if (doc == NULL)
- return (NULL);
- if (doc->oldNs != NULL)
- return (doc->oldNs);
- {
- xmlNsPtr ns;
- ns = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (ns == NULL) {
- xmlTreeErrMemory(
- "allocating the XML namespace");
- return (NULL);
- }
- memset(ns, 0, sizeof(xmlNs));
- ns->type = XML_LOCAL_NAMESPACE;
- ns->href = xmlStrdup(XML_XML_NAMESPACE);
- ns->prefix = xmlStrdup((const xmlChar *)"xml");
- doc->oldNs = ns;
+ xmlNsPtr ns;
+
+ ns = doc->oldNs;
+ if (ns != NULL)
return (ns);
+
+ ns = xmlNewXmlNs();
+ doc->oldNs = ns;
+
+ return(ns);
+}
+
+/**
+ * xmlSearchNsSafe:
+ * @node: a node
+ * @prefix: a namespace prefix
+ * @out: pointer to resulting namespace
+ *
+ * Search a namespace with @prefix in scope of @node.
+ *
+ * Returns 0 on success, -1 if a memory allocation failed, 1 on
+ * other errors.
+ */
+int
+xmlSearchNsSafe(xmlNodePtr node, const xmlChar *prefix,
+ xmlNsPtr *out) {
+ xmlNsPtr cur;
+ xmlDocPtr doc;
+ xmlNodePtr orig = node;
+ xmlNodePtr parent;
+
+ if (out == NULL)
+ return(1);
+ *out = NULL;
+ if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
+ return(1);
+
+ doc = node->doc;
+
+ if ((doc != NULL) && (IS_STR_XML(prefix))) {
+ cur = xmlTreeEnsureXMLDecl(doc);
+ if (cur == NULL)
+ return(-1);
+ *out = cur;
+ return(0);
+ }
+
+ while (node->type != XML_ELEMENT_NODE) {
+ node = node->parent;
+ if (node == NULL)
+ return(0);
+ }
+
+ parent = node;
+
+ while ((node != NULL) && (node->type == XML_ELEMENT_NODE)) {
+ cur = node->nsDef;
+ while (cur != NULL) {
+ if ((xmlStrEqual(cur->prefix, prefix)) &&
+ (cur->href != NULL)) {
+ *out = cur;
+ return(0);
+ }
+ cur = cur->next;
+ }
+ if (orig != node) {
+ cur = node->ns;
+ if ((cur != NULL) &&
+ (xmlStrEqual(cur->prefix, prefix)) &&
+ (cur->href != NULL)) {
+ *out = cur;
+ return(0);
+ }
+ }
+
+ node = node->parent;
+ }
+
+ /*
+ * The XML-1.0 namespace is normally held on the document
+ * element. In this case exceptionally create it on the
+ * node element.
+ */
+ if ((doc == NULL) && (IS_STR_XML(prefix))) {
+ cur = xmlNewXmlNs();
+ if (cur == NULL)
+ return(-1);
+ cur->next = parent->nsDef;
+ parent->nsDef = cur;
+ *out = cur;
}
+
+ return(0);
}
/**
@@ -5946,82 +6108,17 @@ xmlTreeEnsureXMLDecl(xmlDocPtr doc)
* the namespace within those you will be in troubles !!! A warning
* is generated to cover this case.
*
- * Returns the namespace pointer or NULL.
+ * Returns the namespace pointer or NULL if no namespace was found or
+ * a memory allocation failed. Allocations can only fail if the "xml"
+ * namespace is queried.
*/
xmlNsPtr
-xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
-
+xmlSearchNs(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node,
+ const xmlChar *nameSpace) {
xmlNsPtr cur;
- const xmlNode *orig = node;
- if ((node == NULL) || (node->type == XML_NAMESPACE_DECL)) return(NULL);
- if ((nameSpace != NULL) &&
- (xmlStrEqual(nameSpace, (const xmlChar *)"xml"))) {
- if ((doc == NULL) && (node->type == XML_ELEMENT_NODE)) {
- /*
- * The XML-1.0 namespace is normally held on the root
- * element. In this case exceptionally create it on the
- * node element.
- */
- cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (cur == NULL) {
- xmlTreeErrMemory("searching namespace");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNs));
- cur->type = XML_LOCAL_NAMESPACE;
- cur->href = xmlStrdup(XML_XML_NAMESPACE);
- cur->prefix = xmlStrdup((const xmlChar *)"xml");
- cur->next = node->nsDef;
- node->nsDef = cur;
- return(cur);
- }
- if (doc == NULL) {
- doc = node->doc;
- if (doc == NULL)
- return(NULL);
- }
- /*
- * Return the XML namespace declaration held by the doc.
- */
- if (doc->oldNs == NULL)
- return(xmlTreeEnsureXMLDecl(doc));
- else
- return(doc->oldNs);
- }
- while (node != NULL) {
- if ((node->type == XML_ENTITY_REF_NODE) ||
- (node->type == XML_ENTITY_NODE) ||
- (node->type == XML_ENTITY_DECL))
- return(NULL);
- if (node->type == XML_ELEMENT_NODE) {
- cur = node->nsDef;
- while (cur != NULL) {
- if ((cur->prefix == NULL) && (nameSpace == NULL) &&
- (cur->href != NULL))
- return(cur);
- if ((cur->prefix != NULL) && (nameSpace != NULL) &&
- (cur->href != NULL) &&
- (xmlStrEqual(cur->prefix, nameSpace)))
- return(cur);
- cur = cur->next;
- }
- if (orig != node) {
- cur = node->ns;
- if (cur != NULL) {
- if ((cur->prefix == NULL) && (nameSpace == NULL) &&
- (cur->href != NULL))
- return(cur);
- if ((cur->prefix != NULL) && (nameSpace != NULL) &&
- (cur->href != NULL) &&
- (xmlStrEqual(cur->prefix, nameSpace)))
- return(cur);
- }
- }
- }
- node = node->parent;
- }
- return(NULL);
+ xmlSearchNsSafe(node, nameSpace, &cur);
+ return(cur);
}
/**
@@ -6044,7 +6141,6 @@ xmlNsInScope(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node,
while ((node != NULL) && (node != ancestor)) {
if ((node->type == XML_ENTITY_REF_NODE) ||
- (node->type == XML_ENTITY_NODE) ||
(node->type == XML_ENTITY_DECL))
return (-1);
if (node->type == XML_ELEMENT_NODE) {
@@ -6068,92 +6164,117 @@ xmlNsInScope(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node,
}
/**
- * xmlSearchNsByHref:
- * @doc: the document
- * @node: the current node
- * @href: the namespace value
+ * xmlSearchNsByHrefSafe:
+ * @node: a node
+ * @href: a namespace URI
+ * @out: pointer to resulting namespace
*
- * Search a Ns aliasing a given URI. Recurse on the parents until it finds
- * the defined namespace or return NULL otherwise.
- * Returns the namespace pointer or NULL.
+ * Search a namespace matching @URI in scope of @node.
+ *
+ * Returns 0 on success, -1 if a memory allocation failed, 1 on
+ * other errors.
*/
-xmlNsPtr
-xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar * href)
-{
+int
+xmlSearchNsByHrefSafe(xmlNodePtr node, const xmlChar *href,
+ xmlNsPtr *out) {
xmlNsPtr cur;
+ xmlDocPtr doc;
xmlNodePtr orig = node;
+ xmlNodePtr parent;
int is_attr;
- if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) || (href == NULL))
- return (NULL);
- if (xmlStrEqual(href, XML_XML_NAMESPACE)) {
- /*
- * Only the document can hold the XML spec namespace.
- */
- if ((doc == NULL) && (node->type == XML_ELEMENT_NODE)) {
- /*
- * The XML-1.0 namespace is normally held on the root
- * element. In this case exceptionally create it on the
- * node element.
- */
- cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (cur == NULL) {
- xmlTreeErrMemory("searching namespace");
- return (NULL);
- }
- memset(cur, 0, sizeof(xmlNs));
- cur->type = XML_LOCAL_NAMESPACE;
- cur->href = xmlStrdup(XML_XML_NAMESPACE);
- cur->prefix = xmlStrdup((const xmlChar *) "xml");
- cur->next = node->nsDef;
- node->nsDef = cur;
- return (cur);
- }
- if (doc == NULL) {
- doc = node->doc;
- if (doc == NULL)
- return(NULL);
- }
- /*
- * Return the XML namespace declaration held by the doc.
- */
- if (doc->oldNs == NULL)
- return(xmlTreeEnsureXMLDecl(doc));
- else
- return(doc->oldNs);
+ if (out == NULL)
+ return(1);
+ *out = NULL;
+ if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
+ return(1);
+
+ doc = node->doc;
+
+ if ((doc != NULL) && (xmlStrEqual(href, XML_XML_NAMESPACE))) {
+ cur = xmlTreeEnsureXMLDecl(doc);
+ if (cur == NULL)
+ return(-1);
+ *out = cur;
+ return(0);
}
+
is_attr = (node->type == XML_ATTRIBUTE_NODE);
- while (node != NULL) {
- if ((node->type == XML_ENTITY_REF_NODE) ||
- (node->type == XML_ENTITY_NODE) ||
- (node->type == XML_ENTITY_DECL))
- return (NULL);
- if (node->type == XML_ELEMENT_NODE) {
- cur = node->nsDef;
- while (cur != NULL) {
- if ((cur->href != NULL) && (href != NULL) &&
- (xmlStrEqual(cur->href, href))) {
- if (((!is_attr) || (cur->prefix != NULL)) &&
- (xmlNsInScope(doc, orig, node, cur->prefix) == 1))
- return (cur);
+
+ while (node->type != XML_ELEMENT_NODE) {
+ node = node->parent;
+ if (node == NULL)
+ return(0);
+ }
+
+ parent = node;
+
+ while ((node != NULL) && (node->type == XML_ELEMENT_NODE)) {
+ cur = node->nsDef;
+ while (cur != NULL) {
+ if (xmlStrEqual(cur->href, href)) {
+ if (((!is_attr) || (cur->prefix != NULL)) &&
+ (xmlNsInScope(doc, orig, node, cur->prefix) == 1)) {
+ *out = cur;
+ return(0);
}
- cur = cur->next;
}
- if (orig != node) {
- cur = node->ns;
- if (cur != NULL) {
- if ((cur->href != NULL) && (href != NULL) &&
- (xmlStrEqual(cur->href, href))) {
- if (((!is_attr) || (cur->prefix != NULL)) &&
- (xmlNsInScope(doc, orig, node, cur->prefix) == 1))
- return (cur);
+ cur = cur->next;
+ }
+ if (orig != node) {
+ cur = node->ns;
+ if (cur != NULL) {
+ if (xmlStrEqual(cur->href, href)) {
+ if (((!is_attr) || (cur->prefix != NULL)) &&
+ (xmlNsInScope(doc, orig, node,
+ cur->prefix) == 1)) {
+ *out = cur;
+ return(0);
}
}
}
}
+
node = node->parent;
}
- return (NULL);
+
+ /*
+ * The XML-1.0 namespace is normally held on the document
+ * element. In this case exceptionally create it on the
+ * node element.
+ */
+ if ((doc == NULL) && (xmlStrEqual(href, XML_XML_NAMESPACE))) {
+ cur = xmlNewXmlNs();
+ if (cur == NULL)
+ return(-1);
+ cur->next = parent->nsDef;
+ parent->nsDef = cur;
+ *out = cur;
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSearchNsByHref:
+ * @doc: the document
+ * @node: the current node
+ * @href: the namespace value
+ *
+ * Search a Ns aliasing a given URI. Recurse on the parents until it finds
+ * the defined namespace or return NULL otherwise.
+ *
+ * Returns the namespace pointer or NULL if no namespace was found or
+ * a memory allocation failed. Allocations can only fail if the "xml"
+ * namespace is queried.
+ */
+xmlNsPtr
+xmlSearchNsByHref(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node,
+ const xmlChar * href) {
+ xmlNsPtr cur;
+
+ xmlSearchNsByHrefSafe(node, href, &cur);
+ return(cur);
}
/**
@@ -6170,10 +6291,11 @@ xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar * href)
* Returns the (new) namespace definition or NULL in case of error
*/
static xmlNsPtr
-xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
+xmlNewReconciledNs(xmlNodePtr tree, xmlNsPtr ns) {
xmlNsPtr def;
xmlChar prefix[50];
int counter = 1;
+ int res;
if ((tree == NULL) || (tree->type != XML_ELEMENT_NODE)) {
return(NULL);
@@ -6184,7 +6306,9 @@ xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
/*
* Search an existing namespace definition inherited.
*/
- def = xmlSearchNsByHref(doc, tree, ns->href);
+ res = xmlSearchNsByHrefSafe(tree, ns->href, &def);
+ if (res < 0)
+ return(NULL);
if (def != NULL)
return(def);
@@ -6197,7 +6321,9 @@ xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
else
snprintf((char *) prefix, sizeof(prefix), "%.20s", (char *)ns->prefix);
- def = xmlSearchNs(doc, tree, prefix);
+ res = xmlSearchNsSafe(tree, prefix, &def);
+ if (res < 0)
+ return(NULL);
while (def != NULL) {
if (counter > 1000) return(NULL);
if (ns->prefix == NULL)
@@ -6205,7 +6331,9 @@ xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
else
snprintf((char *) prefix, sizeof(prefix), "%.20s%d",
(char *)ns->prefix, counter++);
- def = xmlSearchNs(doc, tree, prefix);
+ res = xmlSearchNsSafe(tree, prefix, &def);
+ if (res < 0)
+ return(NULL);
}
/*
@@ -6216,6 +6344,12 @@ xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
}
#ifdef LIBXML_TREE_ENABLED
+
+typedef struct {
+ xmlNsPtr oldNs;
+ xmlNsPtr newNs;
+} xmlNsCache;
+
/**
* xmlReconciliateNs:
* @doc: the document
@@ -6228,12 +6362,12 @@ xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
* as possible the function try to reuse the existing namespaces found in
* the new environment. If not possible the new namespaces are redeclared
* on @tree at the top of the given subtree.
- * Returns the number of namespace declarations created or -1 in case of error.
+ *
+ * Returns 0 on success or -1 in case of error.
*/
int
xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
- xmlNsPtr *oldNs = NULL;
- xmlNsPtr *newNs = NULL;
+ xmlNsCache *cache = NULL;
int sizeCache = 0;
int nbCache = 0;
@@ -6243,35 +6377,15 @@ xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
int ret = 0, i;
if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) return(-1);
- if ((doc == NULL) || (doc->type != XML_DOCUMENT_NODE)) return(-1);
if (node->doc != doc) return(-1);
while (node != NULL) {
/*
* Reconciliate the node namespace
*/
if (node->ns != NULL) {
- /*
- * initialize the cache if needed
- */
- if (sizeCache == 0) {
- sizeCache = 10;
- oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
- sizeof(xmlNsPtr));
- if (oldNs == NULL) {
- xmlTreeErrMemory("fixing namespaces");
- return(-1);
- }
- newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
- sizeof(xmlNsPtr));
- if (newNs == NULL) {
- xmlTreeErrMemory("fixing namespaces");
- xmlFree(oldNs);
- return(-1);
- }
- }
- for (i = 0;i < nbCache;i++) {
- if (oldNs[i] == node->ns) {
- node->ns = newNs[i];
+ for (i = 0; i < nbCache; i++) {
+ if (cache[i].oldNs == node->ns) {
+ node->ns = cache[i].newNs;
break;
}
}
@@ -6279,32 +6393,31 @@ xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
/*
* OK we need to recreate a new namespace definition
*/
- n = xmlNewReconciledNs(doc, tree, node->ns);
- if (n != NULL) { /* :-( what if else ??? */
+ n = xmlNewReconciledNs(tree, node->ns);
+ if (n == NULL) {
+ ret = -1;
+ } else {
/*
* check if we need to grow the cache buffers.
*/
if (sizeCache <= nbCache) {
- sizeCache *= 2;
- oldNs = (xmlNsPtr *) xmlRealloc(oldNs, sizeCache *
- sizeof(xmlNsPtr));
- if (oldNs == NULL) {
- xmlTreeErrMemory("fixing namespaces");
- xmlFree(newNs);
- return(-1);
- }
- newNs = (xmlNsPtr *) xmlRealloc(newNs, sizeCache *
- sizeof(xmlNsPtr));
- if (newNs == NULL) {
- xmlTreeErrMemory("fixing namespaces");
- xmlFree(oldNs);
- return(-1);
- }
+ xmlNsCache *tmp;
+ size_t newSize = sizeCache ? sizeCache * 2 : 10;
+
+ tmp = xmlRealloc(cache, newSize * sizeof(tmp[0]));
+ if (tmp == NULL) {
+ ret = -1;
+ } else {
+ cache = tmp;
+ sizeCache = newSize;
+ }
}
- newNs[nbCache] = n;
- oldNs[nbCache++] = node->ns;
- node->ns = n;
+ if (nbCache < sizeCache) {
+ cache[nbCache].newNs = n;
+ cache[nbCache++].oldNs = node->ns;
+ }
}
+ node->ns = n;
}
}
/*
@@ -6314,28 +6427,9 @@ xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
attr = node->properties;
while (attr != NULL) {
if (attr->ns != NULL) {
- /*
- * initialize the cache if needed
- */
- if (sizeCache == 0) {
- sizeCache = 10;
- oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
- sizeof(xmlNsPtr));
- if (oldNs == NULL) {
- xmlTreeErrMemory("fixing namespaces");
- return(-1);
- }
- newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
- sizeof(xmlNsPtr));
- if (newNs == NULL) {
- xmlTreeErrMemory("fixing namespaces");
- xmlFree(oldNs);
- return(-1);
- }
- }
- for (i = 0;i < nbCache;i++) {
- if (oldNs[i] == attr->ns) {
- attr->ns = newNs[i];
+ for (i = 0; i < nbCache; i++) {
+ if (cache[i].oldNs == attr->ns) {
+ attr->ns = cache[i].newNs;
break;
}
}
@@ -6343,32 +6437,33 @@ xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
/*
* OK we need to recreate a new namespace definition
*/
- n = xmlNewReconciledNs(doc, tree, attr->ns);
- if (n != NULL) { /* :-( what if else ??? */
+ n = xmlNewReconciledNs(tree, attr->ns);
+ if (n == NULL) {
+ ret = -1;
+ } else {
/*
* check if we need to grow the cache buffers.
*/
if (sizeCache <= nbCache) {
- sizeCache *= 2;
- oldNs = (xmlNsPtr *) xmlRealloc(oldNs,
- sizeCache * sizeof(xmlNsPtr));
- if (oldNs == NULL) {
- xmlTreeErrMemory("fixing namespaces");
- xmlFree(newNs);
- return(-1);
- }
- newNs = (xmlNsPtr *) xmlRealloc(newNs,
- sizeCache * sizeof(xmlNsPtr));
- if (newNs == NULL) {
- xmlTreeErrMemory("fixing namespaces");
- xmlFree(oldNs);
- return(-1);
- }
+ xmlNsCache *tmp;
+ size_t newSize = sizeCache ?
+ sizeCache * 2 : 10;
+
+ tmp = xmlRealloc(cache,
+ newSize * sizeof(tmp[0]));
+ if (tmp == NULL) {
+ ret = -1;
+ } else {
+ cache = tmp;
+ sizeCache = newSize;
+ }
+ }
+ if (nbCache < sizeCache) {
+ cache[nbCache].newNs = n;
+ cache[nbCache++].oldNs = attr->ns;
}
- newNs[nbCache] = n;
- oldNs[nbCache++] = attr->ns;
- attr->ns = n;
}
+ attr->ns = n;
}
}
attr = attr->next;
@@ -6404,10 +6499,8 @@ xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
} else
break;
}
- if (oldNs != NULL)
- xmlFree(oldNs);
- if (newNs != NULL)
- xmlFree(newNs);
+ if (cache != NULL)
+ xmlFree(cache);
return(ret);
}
#endif /* LIBXML_TREE_ENABLED */
@@ -6469,7 +6562,11 @@ xmlGetPropNodeInternal(const xmlNode *node, const xmlChar *name,
*/
if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
tmpstr = xmlStrdup(node->ns->prefix);
+ if (tmpstr == NULL)
+ return(NULL);
tmpstr = xmlStrcat(tmpstr, BAD_CAST ":");
+ if (tmpstr == NULL)
+ return(NULL);
tmpstr = xmlStrcat(tmpstr, node->name);
if (tmpstr == NULL)
return(NULL);
@@ -6545,28 +6642,7 @@ xmlGetPropNodeValueInternal(const xmlAttr *prop)
if (prop == NULL)
return(NULL);
if (prop->type == XML_ATTRIBUTE_NODE) {
- /*
- * Note that we return at least the empty string.
- * TODO: Do we really always want that?
- */
- if (prop->children != NULL) {
- if ((prop->children->next == NULL) &&
- ((prop->children->type == XML_TEXT_NODE) ||
- (prop->children->type == XML_CDATA_SECTION_NODE)))
- {
- /*
- * Optimization for the common case: only 1 text node.
- */
- return(xmlStrdup(prop->children->content));
- } else {
- xmlChar *ret;
-
- ret = xmlNodeListGetString(prop->doc, prop->children, 1);
- if (ret != NULL)
- return(ret);
- }
- }
- return(xmlStrdup((xmlChar *)""));
+ return(xmlNodeGetContent((xmlNodePtr) prop));
} else if (prop->type == XML_ATTRIBUTE_DECL) {
return(xmlStrdup(((xmlAttributePtr)prop)->defaultValue));
}
@@ -6580,10 +6656,11 @@ xmlGetPropNodeValueInternal(const xmlAttr *prop)
*
* Search an attribute associated to a node
* This function also looks in DTD attribute declaration for #FIXED or
- * default declaration values unless DTD use has been turned off.
+ * default declaration values.
*
* Returns the attribute or the attribute declaration or NULL if
- * neither was found.
+ * neither was found. Also returns NULL if a memory allocation failed
+ * making this function unreliable.
*/
xmlAttrPtr
xmlHasProp(const xmlNode *node, const xmlChar *name) {
@@ -6602,7 +6679,6 @@ xmlHasProp(const xmlNode *node, const xmlChar *name) {
}
prop = prop->next;
}
- if (!xmlCheckDTD) return(NULL);
/*
* Check if there is a default declaration in the internal
@@ -6634,16 +6710,53 @@ xmlHasProp(const xmlNode *node, const xmlChar *name) {
* 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.
+ * default declaration values.
* Note that a namespace of NULL indicates to use the default namespace.
*
- * Returns the attribute or the attribute declaration or NULL
- * if neither was found.
+ * Returns the attribute or the attribute declaration or NULL if
+ * neither was found. Also returns NULL if a memory allocation failed
+ * making this function unreliable.
*/
xmlAttrPtr
xmlHasNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace) {
- return(xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD));
+ return(xmlGetPropNodeInternal(node, name, nameSpace, 1));
+}
+
+/**
+ * xmlNodeGetAttrValue:
+ * @node: the node
+ * @name: the attribute name
+ * @nsUri: the URI of the namespace
+ * @out: the returned string
+ *
+ * Search and get the value of an attribute associated to a node
+ * This attribute has to be anchored in the namespace specified.
+ * This does the entity substitution. The returned value must be
+ * freed by the caller.
+ *
+ * Available since 2.13.0.
+ *
+ * Returns 0 on success, 1 if no attribute was found, -1 if a
+ * memory allocation failed.
+ */
+int
+xmlNodeGetAttrValue(const xmlNode *node, const xmlChar *name,
+ const xmlChar *nsUri, xmlChar **out) {
+ xmlAttrPtr prop;
+
+ if (out == NULL)
+ return(1);
+ *out = NULL;
+
+ prop = xmlGetPropNodeInternal(node, name, nsUri, 0);
+ if (prop == NULL)
+ return(1);
+
+ *out = xmlGetPropNodeValueInternal(prop);
+ if (*out == NULL)
+ return(-1);
+ return(0);
}
/**
@@ -6654,13 +6767,17 @@ xmlHasNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace)
* Search and get the value of an attribute associated to a node
* 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.
- * NOTE: this function acts independently of namespaces associated
+ * default declaration values.
+ *
+ * NOTE: This function acts independently of namespaces associated
* to the attribute. Use xmlGetNsProp() or xmlGetNoNsProp()
* for namespace aware processing.
*
- * Returns the attribute value or NULL if not found.
- * It's up to the caller to free the memory with xmlFree().
+ * NOTE: This function doesn't allow to distinguish malloc failures from
+ * missing attributes. It's more robust to use xmlNodeGetAttrValue.
+ *
+ * Returns the attribute value or NULL if not found or a memory allocation
+ * failed. It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
xmlGetProp(const xmlNode *node, const xmlChar *name) {
@@ -6680,18 +6797,21 @@ xmlGetProp(const xmlNode *node, const xmlChar *name) {
* Search and get the value of an attribute associated to a node
* 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.
+ * default declaration values.
* This function is similar to xmlGetProp except it will accept only
* an attribute in no namespace.
*
- * Returns the attribute value or NULL if not found.
- * It's up to the caller to free the memory with xmlFree().
+ * NOTE: This function doesn't allow to distinguish malloc failures from
+ * missing attributes. It's more robust to use xmlNodeGetAttrValue.
+ *
+ * Returns the attribute value or NULL if not found or a memory allocation
+ * failed. It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
xmlGetNoNsProp(const xmlNode *node, const xmlChar *name) {
xmlAttrPtr prop;
- prop = xmlGetPropNodeInternal(node, name, NULL, xmlCheckDTD);
+ prop = xmlGetPropNodeInternal(node, name, NULL, 1);
if (prop == NULL)
return(NULL);
return(xmlGetPropNodeValueInternal(prop));
@@ -6707,16 +6827,19 @@ xmlGetNoNsProp(const xmlNode *node, const xmlChar *name) {
* 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.
+ * default declaration values.
*
- * Returns the attribute value or NULL if not found.
- * It's up to the caller to free the memory with xmlFree().
+ * NOTE: This function doesn't allow to distinguish malloc failures from
+ * missing attributes. It's more robust to use xmlNodeGetAttrValue.
+ *
+ * Returns the attribute value or NULL if not found or a memory allocation
+ * failed. It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace) {
xmlAttrPtr prop;
- prop = xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD);
+ prop = xmlGetPropNodeInternal(node, name, nameSpace, 1);
if (prop == NULL)
return(NULL);
return(xmlGetPropNodeValueInternal(prop));
@@ -6739,7 +6862,7 @@ xmlUnsetProp(xmlNodePtr node, const xmlChar *name) {
prop = xmlGetPropNodeInternal(node, name, NULL, 0);
if (prop == NULL)
return(-1);
- xmlUnlinkNode((xmlNodePtr) prop);
+ xmlUnlinkNodeInternal((xmlNodePtr) prop);
xmlFreeProp(prop);
return(0);
}
@@ -6757,10 +6880,11 @@ int
xmlUnsetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name) {
xmlAttrPtr prop;
- prop = xmlGetPropNodeInternal(node, name, (ns != NULL) ? ns->href : NULL, 0);
+ prop = xmlGetPropNodeInternal(node, name,
+ (ns != NULL) ? ns->href : NULL, 0);
if (prop == NULL)
return(-1);
- xmlUnlinkNode((xmlNodePtr) prop);
+ xmlUnlinkNodeInternal((xmlNodePtr) prop);
xmlFreeProp(prop);
return(0);
}
@@ -6783,8 +6907,10 @@ xmlUnsetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name) {
*/
xmlAttrPtr
xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
- int len;
- const xmlChar *nqname;
+ xmlNsPtr ns = NULL;
+ const xmlChar *localname;
+ xmlChar *prefix;
+ int res;
if ((node == NULL) || (name == NULL) || (node->type != XML_ELEMENT_NODE))
return(NULL);
@@ -6792,16 +6918,19 @@ xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
/*
* handle QNames
*/
- nqname = xmlSplitQName3(name, &len);
- if (nqname != NULL) {
- xmlNsPtr ns;
- xmlChar *prefix = xmlStrndup(name, len);
- ns = xmlSearchNs(node->doc, node, prefix);
- if (prefix != NULL)
- xmlFree(prefix);
- if (ns != NULL)
- return(xmlSetNsProp(node, ns, nqname, value));
+ localname = xmlSplitQName4(name, &prefix);
+ if (localname == NULL)
+ return(NULL);
+
+ if (prefix != NULL) {
+ res = xmlSearchNsSafe(node, prefix, &ns);
+ xmlFree(prefix);
+ if (res < 0)
+ return(NULL);
+ if (ns != NULL)
+ return(xmlSetNsProp(node, ns, localname, value));
}
+
return(xmlSetNsProp(node, NULL, name, value));
}
@@ -6825,11 +6954,22 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
if (ns && (ns->href == NULL))
return(NULL);
- prop = xmlGetPropNodeInternal(node, name, (ns != NULL) ? ns->href : NULL, 0);
+ if (name == NULL)
+ return(NULL);
+ prop = xmlGetPropNodeInternal(node, name,
+ (ns != NULL) ? ns->href : NULL, 0);
if (prop != NULL) {
+ xmlNodePtr children = NULL;
+
/*
* Modify the attribute's value.
*/
+ if (value != NULL) {
+ children = xmlNewDocText(node->doc, value);
+ if (children == NULL)
+ return(NULL);
+ }
+
if (prop->atype == XML_ATTRIBUTE_ID) {
xmlRemoveID(node->doc, prop);
prop->atype = XML_ATTRIBUTE_ID;
@@ -6842,7 +6982,7 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
if (value != NULL) {
xmlNodePtr tmp;
- prop->children = xmlNewDocText(node->doc, value);
+ prop->children = children;
prop->last = NULL;
tmp = prop->children;
while (tmp != NULL) {
@@ -6852,8 +6992,10 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
tmp = tmp->next;
}
}
- if (prop->atype == XML_ATTRIBUTE_ID)
- xmlAddID(NULL, node->doc, value, prop);
+ if ((prop->atype == XML_ATTRIBUTE_ID) &&
+ (xmlAddIDSafe(prop, value) < 0)) {
+ return(NULL);
+ }
return(prop);
}
/*
@@ -6912,33 +7054,25 @@ xmlIsBlankNode(const xmlNode *node) {
* @content: the content
* @len: @content length
*
- * Concat the given string at the end of the existing node content
+ * Concat the given string at the end of the existing node content.
+ *
+ * If @len is -1, the string length will be calculated.
*
* Returns -1 in case of error, 0 otherwise
*/
int
xmlTextConcat(xmlNodePtr node, const xmlChar *content, int len) {
- if (node == NULL) return(-1);
+ if (node == NULL)
+ return(-1);
if ((node->type != XML_TEXT_NODE) &&
(node->type != XML_CDATA_SECTION_NODE) &&
(node->type != XML_COMMENT_NODE) &&
- (node->type != XML_PI_NODE)) {
+ (node->type != XML_PI_NODE))
return(-1);
- }
- /* need to check if content is currently in the dictionary */
- if ((node->content == (xmlChar *) &(node->properties)) ||
- ((node->doc != NULL) && (node->doc->dict != NULL) &&
- xmlDictOwns(node->doc->dict, node->content))) {
- node->content = xmlStrncatNew(node->content, content, len);
- } else {
- node->content = xmlStrncat(node->content, content, len);
- }
- node->properties = NULL;
- if (node->content == NULL)
- return(-1);
- return(0);
+
+ return(xmlTextAddContent(node, content, len));
}
/************************************************************************
@@ -6958,16 +7092,13 @@ xmlBufferCreate(void) {
xmlBufferPtr ret;
ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
- if (ret == NULL) {
- xmlTreeErrMemory("creating buffer");
+ if (ret == NULL)
return(NULL);
- }
ret->use = 0;
ret->size = xmlDefaultBufferSize;
ret->alloc = xmlBufferAllocScheme;
ret->content = (xmlChar *) xmlMallocAtomic(ret->size);
if (ret->content == NULL) {
- xmlTreeErrMemory("creating buffer");
xmlFree(ret);
return(NULL);
}
@@ -6990,17 +7121,14 @@ xmlBufferCreateSize(size_t size) {
if (size >= UINT_MAX)
return(NULL);
ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
- if (ret == NULL) {
- xmlTreeErrMemory("creating buffer");
+ if (ret == NULL)
return(NULL);
- }
ret->use = 0;
ret->alloc = xmlBufferAllocScheme;
ret->size = (size ? size + 1 : 0); /* +1 for ending null */
if (ret->size){
ret->content = (xmlChar *) xmlMallocAtomic(ret->size);
if (ret->content == NULL) {
- xmlTreeErrMemory("creating buffer");
xmlFree(ret);
return(NULL);
}
@@ -7178,10 +7306,8 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
if (len < buf->size - buf->use)
return(0);
- if (len >= UINT_MAX - buf->use) {
- xmlTreeErrMemory("growing buffer past UINT_MAX");
+ if (len >= UINT_MAX - buf->use)
return(-1);
- }
if (buf->size > (size_t) len) {
size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2;
@@ -7194,18 +7320,14 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
size_t start_buf = buf->content - buf->contentIO;
newbuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + size);
- if (newbuf == NULL) {
- xmlTreeErrMemory("growing buffer");
+ if (newbuf == NULL)
return(-1);
- }
buf->contentIO = newbuf;
buf->content = newbuf + start_buf;
} else {
newbuf = (xmlChar *) xmlRealloc(buf->content, size);
- if (newbuf == NULL) {
- xmlTreeErrMemory("growing buffer");
+ if (newbuf == NULL)
return(-1);
- }
buf->content = newbuf;
}
buf->size = size;
@@ -7295,10 +7417,8 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
if (size < buf->size)
return 1;
- if (size > UINT_MAX - 10) {
- xmlTreeErrMemory("growing buffer past UINT_MAX");
+ if (size > UINT_MAX - 10)
return 0;
- }
/* figure out new size */
switch (buf->alloc){
@@ -7306,19 +7426,17 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
case XML_BUFFER_ALLOC_DOUBLEIT:
/*take care of empty case*/
if (buf->size == 0)
- newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);
+ newSize = size + 10;
else
newSize = buf->size;
while (size > newSize) {
- if (newSize > UINT_MAX / 2) {
- xmlTreeErrMemory("growing buffer");
+ if (newSize > UINT_MAX / 2)
return 0;
- }
newSize *= 2;
}
break;
case XML_BUFFER_ALLOC_EXACT:
- newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);
+ newSize = size + 10;
break;
case XML_BUFFER_ALLOC_HYBRID:
if (buf->use < BASE_BUFFER_SIZE)
@@ -7326,17 +7444,15 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
else {
newSize = buf->size;
while (size > newSize) {
- if (newSize > UINT_MAX / 2) {
- xmlTreeErrMemory("growing buffer");
+ if (newSize > UINT_MAX / 2)
return 0;
- }
newSize *= 2;
}
}
break;
default:
- newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);
+ newSize = size + 10;
break;
}
@@ -7351,10 +7467,8 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
buf->size += start_buf;
} else {
rebuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + newSize);
- if (rebuf == NULL) {
- xmlTreeErrMemory("growing buffer");
+ if (rebuf == NULL)
return 0;
- }
buf->contentIO = rebuf;
buf->content = rebuf + start_buf;
}
@@ -7378,10 +7492,8 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
rebuf[buf->use] = 0;
}
}
- if (rebuf == NULL) {
- xmlTreeErrMemory("growing buffer");
+ if (rebuf == NULL)
return 0;
- }
buf->content = rebuf;
}
buf->size = newSize;
@@ -7421,15 +7533,11 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
/* Note that both buf->size and buf->use can be zero here. */
if ((unsigned) len >= buf->size - buf->use) {
- if ((unsigned) len >= UINT_MAX - buf->use) {
- xmlTreeErrMemory("growing buffer past UINT_MAX");
+ if ((unsigned) len >= UINT_MAX - buf->use)
return XML_ERR_NO_MEMORY;
- }
needSize = buf->use + len + 1;
- if (!xmlBufferResize(buf, needSize)){
- xmlTreeErrMemory("growing buffer");
+ if (!xmlBufferResize(buf, needSize))
return XML_ERR_NO_MEMORY;
- }
}
memmove(&buf->content[buf->use], str, len);
@@ -7486,15 +7594,11 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
}
/* Note that both buf->size and buf->use can be zero here. */
if ((unsigned) len >= buf->size - buf->use) {
- if ((unsigned) len >= UINT_MAX - buf->use) {
- xmlTreeErrMemory("growing buffer past UINT_MAX");
+ if ((unsigned) len >= UINT_MAX - buf->use)
return(-1);
- }
needSize = buf->use + len + 1;
- if (!xmlBufferResize(buf, needSize)){
- xmlTreeErrMemory("growing buffer");
- return XML_ERR_NO_MEMORY;
- }
+ if (!xmlBufferResize(buf, needSize))
+ return(-1);
}
memmove(&buf->content[len], &buf->content[0], buf->use);
@@ -7647,6 +7751,8 @@ xmlSetDocCompressMode (xmlDocPtr doc, int mode) {
/**
* xmlGetCompressMode:
*
+ * DEPRECATED: Use xmlGetDocCompressMode
+ *
* get the default compression mode used, ZLIB based.
* Returns 0 (uncompressed) to 9 (max compression)
*/
@@ -7660,6 +7766,8 @@ xmlGetCompressMode(void)
* xmlSetCompressMode:
* @mode: the compression ratio
*
+ * DEPRECATED: Use xmlSetDocCompressMode
+ *
* set the default compression mode used, ZLIB based
* Correct values: 0 (uncompressed) to 9 (max compression)
*/
@@ -7767,10 +7875,8 @@ xmlDOMWrapNsMapAddItem(xmlNsMapPtr *nsmap, int position,
* Create the ns-map.
*/
map = (xmlNsMapPtr) xmlMalloc(sizeof(struct xmlNsMap));
- if (map == NULL) {
- xmlTreeErrMemory("allocating namespace map");
- return (NULL);
- }
+ if (map == NULL)
+ return(NULL);
memset(map, 0, sizeof(struct xmlNsMap));
*nsmap = map;
}
@@ -7787,10 +7893,8 @@ xmlDOMWrapNsMapAddItem(xmlNsMapPtr *nsmap, int position,
* Create a new item.
*/
ret = (xmlNsMapItemPtr) xmlMalloc(sizeof(struct xmlNsMapItem));
- if (ret == NULL) {
- xmlTreeErrMemory("allocating namespace map item");
- return (NULL);
- }
+ if (ret == NULL)
+ return(NULL);
memset(ret, 0, sizeof(struct xmlNsMapItem));
}
@@ -7882,10 +7986,8 @@ xmlDOMWrapNewCtxt(void)
xmlDOMWrapCtxtPtr ret;
ret = xmlMalloc(sizeof(xmlDOMWrapCtxt));
- if (ret == NULL) {
- xmlTreeErrMemory("allocating DOM-wrapper context");
+ if (ret == NULL)
return (NULL);
- }
memset(ret, 0, sizeof(xmlDOMWrapCtxt));
return (ret);
}
@@ -8001,39 +8103,6 @@ xmlDOMWrapNSNormGatherInScopeNs(xmlNsMapPtr *map,
return (0);
}
-/*
-* XML_TREE_ADOPT_STR: If we have a dest-dict, put @str in the dict;
-* otherwise copy it, when it was in the source-dict.
-*/
-#define XML_TREE_ADOPT_STR(str) \
- if (adoptStr && (str != NULL)) { \
- if (destDoc->dict) { \
- const xmlChar *old = str; \
- str = xmlDictLookup(destDoc->dict, str, -1); \
- if ((sourceDoc == NULL) || (sourceDoc->dict == NULL) || \
- (!xmlDictOwns(sourceDoc->dict, old))) \
- xmlFree((char *)old); \
- } else if ((sourceDoc) && (sourceDoc->dict) && \
- xmlDictOwns(sourceDoc->dict, str)) { \
- str = BAD_CAST xmlStrdup(str); \
- } \
- }
-
-/*
-* XML_TREE_ADOPT_STR_2: If @str was in the source-dict, then
-* put it in dest-dict or copy it.
-*/
-#define XML_TREE_ADOPT_STR_2(str) \
- if (adoptStr && (str != NULL) && (sourceDoc != NULL) && \
- (sourceDoc->dict != NULL) && \
- xmlDictOwns(sourceDoc->dict, cur->content)) { \
- if (destDoc->dict) \
- cur->content = (xmlChar *) \
- xmlDictLookup(destDoc->dict, cur->content, -1); \
- else \
- cur->content = xmlStrdup(BAD_CAST cur->content); \
- }
-
/*
* xmlDOMWrapNSNormAddNsMapItem2:
*
@@ -8045,23 +8114,18 @@ static int
xmlDOMWrapNSNormAddNsMapItem2(xmlNsPtr **list, int *size, int *number,
xmlNsPtr oldNs, xmlNsPtr newNs)
{
- if (*list == NULL) {
- *list = (xmlNsPtr *) xmlMalloc(6 * sizeof(xmlNsPtr));
- if (*list == NULL) {
- xmlTreeErrMemory("alloc ns map item");
- return(-1);
- }
- *size = 3;
- *number = 0;
- } else if ((*number) >= (*size)) {
- *size *= 2;
- *list = (xmlNsPtr *) xmlRealloc(*list,
- (*size) * 2 * sizeof(xmlNsPtr));
- if (*list == NULL) {
- xmlTreeErrMemory("realloc ns map item");
- return(-1);
- }
+ if (*number >= *size) {
+ xmlNsPtr *tmp;
+ size_t newSize;
+
+ newSize = *size ? *size * 2 : 3;
+ tmp = xmlRealloc(*list, newSize * 2 * sizeof(tmp[0]));
+ if (tmp == NULL)
+ return(-1);
+ *list = tmp;
+ *size = newSize;
}
+
(*list)[2 * (*number)] = oldNs;
(*list)[2 * (*number) +1] = newNs;
(*number)++;
@@ -8090,7 +8154,7 @@ xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc,
xmlNodePtr node, int options ATTRIBUTE_UNUSED)
{
xmlNsPtr *list = NULL;
- int sizeList, nbList, i, j;
+ int sizeList = 0, nbList = 0, ret = 0, i, j;
xmlNsPtr ns;
if ((node == NULL) || (doc == NULL) || (node->doc != doc))
@@ -8106,7 +8170,7 @@ xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc,
case XML_ENTITY_REF_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
- xmlUnlinkNode(node);
+ xmlUnlinkNodeInternal(node);
return (0);
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
@@ -8114,7 +8178,7 @@ xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc,
default:
return (1);
}
- xmlUnlinkNode(node);
+ xmlUnlinkNodeInternal(node);
/*
* Save out-of-scope ns-references in doc->oldNs.
*/
@@ -8126,7 +8190,7 @@ xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc,
do {
if (xmlDOMWrapNSNormAddNsMapItem2(&list, &sizeList,
&nbList, ns, ns) == -1)
- goto internal_error;
+ ret = -1;
ns = ns->next;
} while (ns != NULL);
}
@@ -8156,7 +8220,7 @@ xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc,
ns = xmlDOMWrapStoreNs(doc, node->ns->href,
node->ns->prefix);
if (ns == NULL)
- goto internal_error;
+ ret = -1;
}
if (ns != NULL) {
/*
@@ -8164,7 +8228,7 @@ xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc,
*/
if (xmlDOMWrapNSNormAddNsMapItem2(&list, &sizeList,
&nbList, node->ns, ns) == -1)
- goto internal_error;
+ ret = -1;
}
node->ns = ns;
}
@@ -8189,19 +8253,22 @@ xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc,
if (node->next != NULL)
node = node->next;
else {
+ int type = node->type;
+
node = node->parent;
- goto next_sibling;
+ if ((type == XML_ATTRIBUTE_NODE) &&
+ (node != NULL) &&
+ (node->children != NULL)) {
+ node = node->children;
+ } else {
+ goto next_sibling;
+ }
}
} while (node != NULL);
if (list != NULL)
xmlFree(list);
- return (0);
-
-internal_error:
- if (list != NULL)
- xmlFree(list);
- return (-1);
+ return (ret);
}
/*
@@ -8299,8 +8366,7 @@ xmlSearchNsByNamespaceStrict(xmlDocPtr doc, xmlNodePtr node,
out = prev;
prev = cur;
}
- } else if ((cur->type == XML_ENTITY_NODE) ||
- (cur->type == XML_ENTITY_DECL))
+ } else if (cur->type == XML_ENTITY_DECL)
return (0);
cur = cur->parent;
} while ((cur != NULL) && (cur->doc != (xmlDocPtr) cur));
@@ -8362,8 +8428,7 @@ xmlSearchNsByPrefixStrict(xmlDocPtr doc, xmlNodePtr node,
ns = ns->next;
} while (ns != NULL);
}
- } else if ((cur->type == XML_ENTITY_NODE) ||
- (cur->type == XML_ENTITY_DECL))
+ } else if (cur->type == XML_ENTITY_DECL)
return (0);
cur = cur->parent;
} while ((cur != NULL) && (cur->doc != (xmlDocPtr) cur));
@@ -8547,7 +8612,6 @@ xmlDOMWrapNSNormAcquireNormalizedNs(xmlDocPtr doc,
*/
if (xmlDOMWrapNsMapAddItem(nsMap, -1, ns,
tmpns, XML_TREE_NSMAP_DOC) == NULL) {
- xmlFreeNs(tmpns);
return (-1);
}
*retNs = tmpns;
@@ -8577,7 +8641,6 @@ xmlDOMWrapNSNormAcquireNormalizedNs(xmlDocPtr doc,
}
}
if (xmlDOMWrapNsMapAddItem(nsMap, -1, ns, tmpns, depth) == NULL) {
- xmlFreeNs(tmpns);
return (-1);
}
*retNs = tmpns;
@@ -8622,7 +8685,7 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
int optRemoveRedundantNS =
((xmlDOMReconcileNSOptions) options & XML_DOM_RECONNS_REMOVEREDUND) ? 1 : 0;
xmlNsPtr *listRedund = NULL;
- int sizeRedund = 0, nbRedund = 0, ret, i, j;
+ int sizeRedund = 0, nbRedund = 0, ret = 0, i, j;
if ((elem == NULL) || (elem->doc == NULL) ||
(elem->type != XML_ELEMENT_NODE))
@@ -8651,7 +8714,7 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
*/
if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap,
elem->parent) == -1)
- goto internal_error;
+ ret = -1;
}
parnsdone = 1;
}
@@ -8673,16 +8736,18 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
* Add it to the list of redundant ns-decls.
*/
if (xmlDOMWrapNSNormAddNsMapItem2(&listRedund,
- &sizeRedund, &nbRedund, ns, mi->newNs) == -1)
- goto internal_error;
- /*
- * Remove the ns-decl from the element-node.
- */
- if (prevns)
- prevns->next = ns->next;
- else
- cur->nsDef = ns->next;
- goto next_ns_decl;
+ &sizeRedund, &nbRedund, ns, mi->newNs) == -1) {
+ ret = -1;
+ } else {
+ /*
+ * Remove the ns-decl from the element-node.
+ */
+ if (prevns)
+ prevns->next = ns->next;
+ else
+ cur->nsDef = ns->next;
+ goto next_ns_decl;
+ }
}
}
}
@@ -8712,7 +8777,7 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
*/
if (xmlDOMWrapNsMapAddItem(&nsMap, -1, ns, ns,
depth) == NULL)
- goto internal_error;
+ ret = -1;
prevns = ns;
next_ns_decl:
@@ -8732,7 +8797,7 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
((xmlNodePtr) elem->parent->doc != elem->parent)) {
if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap,
elem->parent) == -1)
- goto internal_error;
+ ret = -1;
}
parnsdone = 1;
}
@@ -8771,7 +8836,7 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
&nsMap, depth,
ancestorsOnly,
(cur->type == XML_ATTRIBUTE_NODE) ? 1 : 0) == -1)
- goto internal_error;
+ ret = -1;
cur->ns = ns;
ns_end:
@@ -8831,11 +8896,6 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
}
} while (cur != NULL);
- ret = 0;
- goto exit;
-internal_error:
- ret = -1;
-exit:
if (listRedund) {
for (i = 0, j = 0; i < nbRedund; i++, j += 2) {
xmlFreeNs(listRedund[j]);
@@ -8871,7 +8931,7 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
*/
static int
xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
- xmlDocPtr sourceDoc,
+ xmlDocPtr sourceDoc ATTRIBUTE_UNUSED,
xmlNodePtr node,
xmlDocPtr destDoc,
xmlNodePtr destParent,
@@ -8882,21 +8942,12 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
xmlNsMapPtr nsMap = NULL;
xmlNsMapItemPtr mi;
xmlNsPtr ns = NULL;
- int depth = -1, adoptStr = 1;
+ int depth = -1;
/* gather @parent's ns-decls. */
int parnsdone;
/* @ancestorsOnly should be set per option. */
int ancestorsOnly = 0;
- /*
- * Optimize string adoption for equal or none dicts.
- */
- if ((sourceDoc != NULL) &&
- (sourceDoc->dict == destDoc->dict))
- adoptStr = 0;
- else
- adoptStr = 1;
-
/*
* Get the ns-map from the context if available.
*/
@@ -8916,40 +8967,21 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
parnsdone = 0;
cur = node;
- if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL))
- goto internal_error;
while (cur != NULL) {
- /*
- * Paranoid source-doc sanity check.
- */
- if (cur->doc != sourceDoc) {
- /*
- * We'll assume XIncluded nodes if the doc differs.
- * TODO: Do we need to reconciliate XIncluded nodes?
- * This here skips XIncluded nodes and tries to handle
- * broken sequences.
- */
- if (cur->next == NULL)
- goto leave_node;
- do {
- cur = cur->next;
- if ((cur->type == XML_XINCLUDE_END) ||
- (cur->doc == node->doc))
- break;
- } while (cur->next != NULL);
+ if (cur->doc != destDoc) {
+ if (xmlNodeSetDoc(cur, destDoc) < 0)
+ ret = -1;
+ }
- if (cur->doc != node->doc)
- goto leave_node;
- }
- cur->doc = destDoc;
switch (cur->type) {
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
/*
* TODO
*/
- return (-1);
+ ret = -1;
+ goto leave_node;
case XML_ELEMENT_NODE:
curElem = cur;
depth++;
@@ -8970,14 +9002,12 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
*/
if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap,
destParent) == -1)
- goto internal_error;
+ ret = -1;
parnsdone = 1;
}
for (ns = cur->nsDef; ns != NULL; ns = ns->next) {
/*
* NOTE: ns->prefix and ns->href are never in the dict.
- * XML_TREE_ADOPT_STR(ns->prefix)
- * XML_TREE_ADOPT_STR(ns->href)
*/
/*
* Does it shadow any ns-decl?
@@ -8999,7 +9029,7 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
*/
if (xmlDOMWrapNsMapAddItem(&nsMap, -1,
ns, ns, depth) == NULL)
- goto internal_error;
+ ret = -1;
}
}
/* Falls through. */
@@ -9011,7 +9041,7 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
if (! parnsdone) {
if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap,
destParent) == -1)
- goto internal_error;
+ ret = -1;
parnsdone = 1;
}
/*
@@ -9045,7 +9075,7 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
*/
if (xmlDOMWrapNsMapAddItem(&nsMap, -1,
cur->ns, ns, XML_TREE_NSMAP_CUSTOM) == NULL)
- goto internal_error;
+ ret = -1;
cur->ns = ns;
} else {
/*
@@ -9059,15 +9089,11 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
ancestorsOnly,
/* ns-decls must be prefixed for attributes. */
(cur->type == XML_ATTRIBUTE_NODE) ? 1 : 0) == -1)
- goto internal_error;
+ ret = -1;
cur->ns = ns;
}
+
ns_end:
- /*
- * Further node properties.
- * TODO: Is this all?
- */
- XML_TREE_ADOPT_STR(cur->name)
if (cur->type == XML_ELEMENT_NODE) {
cur->psvi = NULL;
cur->line = 0;
@@ -9082,55 +9108,16 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
cur = (xmlNodePtr) cur->properties;
continue;
}
- } else {
- /*
- * Attributes.
- */
- if ((sourceDoc != NULL) &&
- (((xmlAttrPtr) cur)->atype == XML_ATTRIBUTE_ID))
- {
- xmlRemoveID(sourceDoc, (xmlAttrPtr) cur);
- }
- ((xmlAttrPtr) cur)->atype = 0;
- ((xmlAttrPtr) cur)->psvi = NULL;
}
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
- /*
- * This puts the content in the dest dict, only if
- * it was previously in the source dict.
- */
- XML_TREE_ADOPT_STR_2(cur->content)
- goto leave_node;
- case XML_ENTITY_REF_NODE:
- /*
- * Remove reference to the entity-node.
- */
- cur->content = NULL;
- cur->children = NULL;
- cur->last = NULL;
- if ((destDoc->intSubset) || (destDoc->extSubset)) {
- xmlEntityPtr ent;
- /*
- * Assign new entity-node if available.
- */
- ent = xmlGetDocEntity(destDoc, cur->name);
- if (ent != NULL) {
- cur->content = ent->content;
- cur->children = (xmlNodePtr) ent;
- cur->last = (xmlNodePtr) ent;
- }
- }
- goto leave_node;
case XML_PI_NODE:
- XML_TREE_ADOPT_STR(cur->name)
- XML_TREE_ADOPT_STR_2(cur->content)
- break;
case XML_COMMENT_NODE:
- break;
+ case XML_ENTITY_REF_NODE:
+ goto leave_node;
default:
- goto internal_error;
+ ret = -1;
}
/*
* Walk the tree.
@@ -9181,12 +9168,6 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
}
}
- goto exit;
-
-internal_error:
- ret = -1;
-
-exit:
/*
* Cleanup.
*/
@@ -9248,7 +9229,7 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
int options ATTRIBUTE_UNUSED)
{
int ret = 0;
- xmlNodePtr cur, curElem = NULL;
+ xmlNodePtr cur, cloneElem = NULL;
xmlNsMapPtr nsMap = NULL;
xmlNsMapItemPtr mi;
xmlNsPtr ns;
@@ -9266,7 +9247,8 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
xmlNsPtr cloneNs = NULL, *cloneNsDefSlot = NULL;
xmlDictPtr dict; /* The destination dict */
- if ((node == NULL) || (resNode == NULL) || (destDoc == NULL))
+ if ((node == NULL) || (resNode == NULL) || (destDoc == NULL) ||
+ ((destParent != NULL) && (destParent->doc != destDoc)))
return(-1);
/*
* TODO: Initially we support only element-nodes.
@@ -9298,9 +9280,6 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
*resNode = NULL;
cur = node;
- if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL))
- return(-1);
-
while (cur != NULL) {
if (cur->doc != sourceDoc) {
/*
@@ -9328,15 +9307,12 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
case XML_PI_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
/*
* Nodes of xmlNode structure.
*/
clone = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (clone == NULL) {
- xmlTreeErrMemory("xmlDOMWrapCloneNode(): allocating a node");
+ if (clone == NULL)
goto internal_error;
- }
memset(clone, 0, sizeof(xmlNode));
/*
* Set hierarchical links.
@@ -9348,6 +9324,7 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
clone->prev = prevClone;
} else
parentClone->children = clone;
+ parentClone->last = clone;
} else
resultClone = clone;
@@ -9358,10 +9335,8 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
*/
/* Use xmlRealloc to avoid -Warray-bounds warning */
clone = (xmlNodePtr) xmlRealloc(NULL, sizeof(xmlAttr));
- if (clone == NULL) {
- xmlTreeErrMemory("xmlDOMWrapCloneNode(): allocating an attr-node");
+ if (clone == NULL)
goto internal_error;
- }
memset(clone, 0, sizeof(xmlAttr));
/*
* Set hierarchical links.
@@ -9402,7 +9377,12 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
else if (cur->name == xmlStringComment)
clone->name = xmlStringComment;
else if (cur->name != NULL) {
- DICT_CONST_COPY(cur->name, clone->name);
+ if (dict != NULL)
+ clone->name = xmlDictLookup(dict, cur->name, -1);
+ else
+ clone->name = xmlStrdup(cur->name);
+ if (clone->name == NULL)
+ goto internal_error;
}
switch (cur->type) {
@@ -9413,7 +9393,7 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
*/
return (-1);
case XML_ELEMENT_NODE:
- curElem = cur;
+ cloneElem = clone;
depth++;
/*
* Namespace declarations.
@@ -9439,18 +9419,25 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
* Create a new xmlNs.
*/
cloneNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (cloneNs == NULL) {
- xmlTreeErrMemory("xmlDOMWrapCloneNode(): "
- "allocating namespace");
- return(-1);
- }
+ if (cloneNs == NULL)
+ goto internal_error;
memset(cloneNs, 0, sizeof(xmlNs));
cloneNs->type = XML_LOCAL_NAMESPACE;
- if (ns->href != NULL)
+ if (ns->href != NULL) {
cloneNs->href = xmlStrdup(ns->href);
- if (ns->prefix != NULL)
+ if (cloneNs->href == NULL) {
+ xmlFreeNs(cloneNs);
+ goto internal_error;
+ }
+ }
+ if (ns->prefix != NULL) {
cloneNs->prefix = xmlStrdup(ns->prefix);
+ if (cloneNs->prefix == NULL) {
+ xmlFreeNs(cloneNs);
+ goto internal_error;
+ }
+ }
*cloneNsDefSlot = cloneNs;
cloneNsDefSlot = &(cloneNs->next);
@@ -9496,15 +9483,18 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
/* IDs will be processed further down. */
/* cur->ns will be processed further down. */
break;
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
/*
* Note that this will also cover the values of attributes.
*/
- DICT_COPY(cur->content, clone->content);
- goto leave_node;
- case XML_ENTITY_NODE:
- /* TODO: What to do here? */
+ if (cur->content != NULL) {
+ clone->content = xmlStrdup(cur->content);
+ if (clone->content == NULL)
+ goto internal_error;
+ }
goto leave_node;
case XML_ENTITY_REF_NODE:
if (sourceDoc != destDoc) {
@@ -9530,12 +9520,6 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
clone->last = cur->last;
}
goto leave_node;
- case XML_PI_NODE:
- DICT_COPY(cur->content, clone->content);
- goto leave_node;
- case XML_COMMENT_NODE:
- DICT_COPY(cur->content, clone->content);
- goto leave_node;
default:
goto internal_error;
}
@@ -9595,8 +9579,8 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
* Acquire a normalized ns-decl and add it to the map.
*/
if (xmlDOMWrapNSNormAcquireNormalizedNs(destDoc,
- /* ns-decls on curElem or on destDoc->oldNs */
- destParent ? curElem : NULL,
+ /* ns-decls on cloneElem or on destDoc->oldNs */
+ destParent ? cloneElem : NULL,
cur->ns, &ns,
&nsMap, depth,
/* if we need to search only in the ancestor-axis */
@@ -9617,19 +9601,22 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
if ((clone->type == XML_ATTRIBUTE_NODE) &&
(clone->parent != NULL))
{
- if (xmlIsID(destDoc, clone->parent, (xmlAttrPtr) clone)) {
+ int res;
+ res = xmlIsID(destDoc, clone->parent, (xmlAttrPtr) clone);
+ if (res < 0)
+ goto internal_error;
+ if (res == 1) {
xmlChar *idVal;
- idVal = xmlNodeListGetString(cur->doc, cur->children, 1);
- if (idVal != NULL) {
- if (xmlAddID(NULL, destDoc, idVal, (xmlAttrPtr) cur) == NULL) {
- /* TODO: error message. */
- xmlFree(idVal);
- goto internal_error;
- }
- xmlFree(idVal);
- }
+ idVal = xmlNodeGetContent(cur);
+ if (idVal == NULL)
+ goto internal_error;
+ if (xmlAddIDSafe((xmlAttrPtr) cur, idVal) < 0) {
+ xmlFree(idVal);
+ goto internal_error;
+ }
+ xmlFree(idVal);
}
}
/*
@@ -9694,11 +9681,6 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
prevClone = clone;
cur = cur->next;
} else if (cur->type != XML_ATTRIBUTE_NODE) {
- /*
- * Set clone->last.
- */
- if (clone->parent != NULL)
- clone->parent->last = clone;
clone = clone->parent;
if (clone != NULL)
parentClone = clone->parent;
@@ -9767,19 +9749,22 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
*/
static int
xmlDOMWrapAdoptAttr(xmlDOMWrapCtxtPtr ctxt,
- xmlDocPtr sourceDoc,
+ xmlDocPtr sourceDoc ATTRIBUTE_UNUSED,
xmlAttrPtr attr,
xmlDocPtr destDoc,
xmlNodePtr destParent,
int options ATTRIBUTE_UNUSED)
{
- xmlNodePtr cur;
- int adoptStr = 1;
+ int ret = 0;
if ((attr == NULL) || (destDoc == NULL))
return (-1);
- attr->doc = destDoc;
+ if (attr->doc != destDoc) {
+ if (xmlSetTreeDoc((xmlNodePtr) attr, destDoc) < 0)
+ ret = -1;
+ }
+
if (attr->ns != NULL) {
xmlNsPtr ns = NULL;
@@ -9800,75 +9785,18 @@ xmlDOMWrapAdoptAttr(xmlDOMWrapCtxtPtr ctxt,
*/
if (xmlSearchNsByNamespaceStrict(destDoc, destParent, attr->ns->href,
&ns, 1) == -1)
- goto internal_error;
+ ret = -1;
if (ns == NULL) {
ns = xmlDOMWrapNSNormDeclareNsForced(destDoc, destParent,
attr->ns->href, attr->ns->prefix, 1);
}
}
if (ns == NULL)
- goto internal_error;
+ ret = -1;
attr->ns = ns;
}
- XML_TREE_ADOPT_STR(attr->name);
- attr->atype = 0;
- attr->psvi = NULL;
- /*
- * Walk content.
- */
- if (attr->children == NULL)
- return (0);
- cur = attr->children;
- if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL))
- goto internal_error;
- while (cur != NULL) {
- cur->doc = destDoc;
- switch (cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- XML_TREE_ADOPT_STR_2(cur->content)
- break;
- case XML_ENTITY_REF_NODE:
- /*
- * Remove reference to the entity-node.
- */
- cur->content = NULL;
- cur->children = NULL;
- cur->last = NULL;
- if ((destDoc->intSubset) || (destDoc->extSubset)) {
- xmlEntityPtr ent;
- /*
- * Assign new entity-node if available.
- */
- ent = xmlGetDocEntity(destDoc, cur->name);
- if (ent != NULL) {
- cur->content = ent->content;
- cur->children = (xmlNodePtr) ent;
- cur->last = (xmlNodePtr) ent;
- }
- }
- break;
- default:
- break;
- }
- if (cur->children != NULL) {
- cur = cur->children;
- continue;
- }
-next_sibling:
- if (cur == (xmlNodePtr) attr)
- break;
- if (cur->next != NULL)
- cur = cur->next;
- else {
- cur = cur->parent;
- goto next_sibling;
- }
- }
- return (0);
-internal_error:
- return (-1);
+ return (ret);
}
/*
@@ -9906,6 +9834,8 @@ xmlDOMWrapAdoptNode(xmlDOMWrapCtxtPtr ctxt,
xmlNodePtr destParent,
int options)
{
+ int ret = 0;
+
if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) ||
(destDoc == NULL) ||
((destParent != NULL) && (destParent->doc != destDoc)))
@@ -9913,17 +9843,18 @@ xmlDOMWrapAdoptNode(xmlDOMWrapCtxtPtr ctxt,
/*
* Check node->doc sanity.
*/
- if ((node->doc != NULL) && (sourceDoc != NULL) &&
- (node->doc != sourceDoc)) {
- /*
- * Might be an XIncluded node.
- */
+ if (sourceDoc == NULL) {
+ sourceDoc = node->doc;
+ } else if (node->doc != sourceDoc) {
return (-1);
}
- if (sourceDoc == NULL)
- sourceDoc = node->doc;
+
+ /*
+ * TODO: Shouldn't this be allowed?
+ */
if (sourceDoc == destDoc)
return (-1);
+
switch (node->type) {
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
@@ -9943,7 +9874,7 @@ xmlDOMWrapAdoptNode(xmlDOMWrapCtxtPtr ctxt,
* Unlink only if @node was not already added to @destParent.
*/
if ((node->parent != NULL) && (destParent != node->parent))
- xmlUnlinkNode(node);
+ xmlUnlinkNodeInternal(node);
if (node->type == XML_ELEMENT_NODE) {
return (xmlDOMWrapAdoptBranch(ctxt, sourceDoc, node,
@@ -9952,52 +9883,12 @@ xmlDOMWrapAdoptNode(xmlDOMWrapCtxtPtr ctxt,
return (xmlDOMWrapAdoptAttr(ctxt, sourceDoc,
(xmlAttrPtr) node, destDoc, destParent, options));
} else {
- xmlNodePtr cur = node;
- int adoptStr = 1;
-
- cur->doc = destDoc;
- /*
- * Optimize string adoption.
- */
- if ((sourceDoc != NULL) &&
- (sourceDoc->dict == destDoc->dict))
- adoptStr = 0;
- switch (node->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- XML_TREE_ADOPT_STR_2(node->content)
- break;
- case XML_ENTITY_REF_NODE:
- /*
- * Remove reference to the entity-node.
- */
- node->content = NULL;
- node->children = NULL;
- node->last = NULL;
- if ((destDoc->intSubset) || (destDoc->extSubset)) {
- xmlEntityPtr ent;
- /*
- * Assign new entity-node if available.
- */
- ent = xmlGetDocEntity(destDoc, node->name);
- if (ent != NULL) {
- node->content = ent->content;
- node->children = (xmlNodePtr) ent;
- node->last = (xmlNodePtr) ent;
- }
- }
- XML_TREE_ADOPT_STR(node->name)
- break;
- case XML_PI_NODE: {
- XML_TREE_ADOPT_STR(node->name)
- XML_TREE_ADOPT_STR_2(node->content)
- break;
- }
- default:
- break;
- }
+ if (node->doc != destDoc) {
+ if (xmlNodeSetDoc(node, destDoc) < 0)
+ ret = -1;
+ }
}
- return (0);
+ return (ret);
}
/************************************************************************
@@ -10055,6 +9946,8 @@ xmlIsXHTML(const xmlChar *systemID, const xmlChar *publicID) {
* xmlRegisterNodeDefault:
* @func: function pointer to the new RegisterNodeFunc
*
+ * DEPRECATED: don't use
+ *
* Registers a callback for node creation
*
* Returns the old value of the registration function
@@ -10073,6 +9966,8 @@ xmlRegisterNodeDefault(xmlRegisterNodeFunc func)
* xmlDeregisterNodeDefault:
* @func: function pointer to the new DeregisterNodeFunc
*
+ * DEPRECATED: don't use
+ *
* Registers a callback for node destruction
*
* Returns the previous value of the deregistration function
diff --git a/trio.c b/trio.c
deleted file mode 100644
index 31b3b37..0000000
--- a/trio.c
+++ /dev/null
@@ -1,6892 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- *************************************************************************
- *
- * A note to trio contributors:
- *
- * Avoid heap allocation at all costs to ensure that the trio functions
- * are async-safe. The exceptions are the printf/fprintf functions, which
- * uses fputc, and the asprintf functions and the modifier, which
- * by design are required to allocate form the heap.
- *
- ************************************************************************/
-
-/*
- * TODO:
- * - Scan is probably too permissive about its modifiers.
- * - C escapes in %#[] ?
- * - Multibyte characters (done for format parsing, except scan groups)
- * - Complex numbers? (C99 _Complex)
- * - Boolean values? (C99 _Bool)
- * - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used
- * to print the mantissa, e.g. NaN(0xc000000000000000)
- * - Should we support the GNU %a alloc modifier? GNU has an ugly hack
- * for %a, because C99 used %a for other purposes. If specified as
- * %as or %a[ it is interpreted as the alloc modifier, otherwise as
- * the C99 hex-float. This means that you cannot scan %as as a hex-float
- * immediately followed by an 's'.
- * - Scanning of collating symbols.
- */
-
-/*************************************************************************
- * Trio include files
- */
-#include "triodef.h"
-#include "trio.h"
-#include "triop.h"
-#include "trionan.h"
-#if !defined(TRIO_MINIMAL)
-# include "triostr.h"
-#endif
-
-/**************************************************************************
- *
- * Definitions
- *
- *************************************************************************/
-
-#include
-#include
-#include
-
-#if (defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) \
- || defined(USE_MULTIBYTE) || TRIO_WIDECHAR) \
- && !defined(_WIN32_WCE)
-# define TRIO_COMPILER_SUPPORTS_MULTIBYTE
-# if !defined(MB_LEN_MAX)
-# define MB_LEN_MAX 6
-# endif
-#endif
-
-#if (defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1100)) || defined(TRIO_COMPILER_BCB)
-# define TRIO_COMPILER_SUPPORTS_MSVC_INT
-#endif
-
-#if defined(_WIN32_WCE)
-#include
-#endif
-
-/*************************************************************************
- * Generic definitions
- */
-
-#if !(defined(DEBUG) || defined(NDEBUG))
-# define NDEBUG
-#endif
-
-#include
-#include
-#if !defined(TRIO_COMPILER_SUPPORTS_C99)
-# define isblank(x) (((x)==32) || ((x)==9))
-#endif
-#if defined(TRIO_COMPILER_ANCIENT)
-# include
-#else
-# include
-#endif
-#include
-#include
-
-#ifndef NULL
-# define NULL 0
-#endif
-#define NIL ((char)0)
-#ifndef FALSE
-# define FALSE (1 == 0)
-# define TRUE (! FALSE)
-#endif
-#define BOOLEAN_T int
-
-/* mincore() can be used for debugging purposes */
-#define VALID(x) (NULL != (x))
-
-#if TRIO_ERRORS
- /*
- * Encode the error code and the position. This is decoded
- * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.
- */
-# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))
-#else
-# define TRIO_ERROR_RETURN(x,y) (-1)
-#endif
-
-#ifndef VA_LIST_IS_ARRAY
-#define TRIO_VA_LIST_PTR va_list *
-#define TRIO_VA_LIST_ADDR(l) (&(l))
-#define TRIO_VA_LIST_DEREF(l) (*(l))
-#else
-#define TRIO_VA_LIST_PTR va_list
-#define TRIO_VA_LIST_ADDR(l) (l)
-#define TRIO_VA_LIST_DEREF(l) (l)
-#endif
-
-typedef unsigned long trio_flags_t;
-
-
-/*************************************************************************
- * Platform specific definitions
- */
-#if defined(TRIO_PLATFORM_UNIX) || defined(TRIO_PLATFORM_OS400)
-# include
-# include
-# include
-# define USE_LOCALE
-#endif /* TRIO_PLATFORM_UNIX */
-#if defined(TRIO_PLATFORM_VMS)
-# include
-#endif
-#if defined(TRIO_PLATFORM_WIN32)
-# if defined(_WIN32_WCE)
-# include
-# else
-# include
-# define read _read
-# define write _write
-# endif
-#endif /* TRIO_PLATFORM_WIN32 */
-
-#if TRIO_WIDECHAR
-# if defined(TRIO_COMPILER_SUPPORTS_ISO94)
-# include
-# include
-typedef wchar_t trio_wchar_t;
-typedef wint_t trio_wint_t;
-# else
-typedef char trio_wchar_t;
-typedef int trio_wint_t;
-# define WCONST(x) L ## x
-# define WEOF EOF
-# define iswalnum(x) isalnum(x)
-# define iswalpha(x) isalpha(x)
-# define iswblank(x) isblank(x)
-# define iswcntrl(x) iscntrl(x)
-# define iswdigit(x) isdigit(x)
-# define iswgraph(x) isgraph(x)
-# define iswlower(x) islower(x)
-# define iswprint(x) isprint(x)
-# define iswpunct(x) ispunct(x)
-# define iswspace(x) isspace(x)
-# define iswupper(x) isupper(x)
-# define iswxdigit(x) isxdigit(x)
-# endif
-#endif
-
-
-/*************************************************************************
- * Compiler dependent definitions
- */
-
-/* Support for long long */
-#ifndef __cplusplus
-# if !defined(USE_LONGLONG)
-# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__)
-# define USE_LONGLONG
-# elif defined(TRIO_COMPILER_SUNPRO)
-# define USE_LONGLONG
-# elif defined(_LONG_LONG) || defined(_LONGLONG)
-# define USE_LONGLONG
-# endif
-# endif
-#endif
-
-/* The extra long numbers */
-#if defined(USE_LONGLONG)
-typedef signed long long int trio_longlong_t;
-typedef unsigned long long int trio_ulonglong_t;
-#elif defined(TRIO_COMPILER_SUPPORTS_MSVC_INT)
-typedef signed __int64 trio_longlong_t;
-typedef unsigned __int64 trio_ulonglong_t;
-#else
-typedef TRIO_SIGNED long int trio_longlong_t;
-typedef unsigned long int trio_ulonglong_t;
-#endif
-
-/* Maximal and fixed integer types */
-#if defined(TRIO_COMPILER_SUPPORTS_C99) && !defined( __VMS )
-# include
-typedef intmax_t trio_intmax_t;
-typedef uintmax_t trio_uintmax_t;
-typedef int8_t trio_int8_t;
-typedef int16_t trio_int16_t;
-typedef int32_t trio_int32_t;
-typedef int64_t trio_int64_t;
-#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98) || defined( __VMS )
-# include
-#ifdef __VMS
-typedef long long int intmax_t;
-typedef unsigned long long int uintmax_t;
-#endif
-typedef intmax_t trio_intmax_t;
-typedef uintmax_t trio_uintmax_t;
-typedef int8_t trio_int8_t;
-typedef int16_t trio_int16_t;
-typedef int32_t trio_int32_t;
-typedef int64_t trio_int64_t;
-#elif defined(TRIO_COMPILER_SUPPORTS_MSVC_INT)
-typedef trio_longlong_t trio_intmax_t;
-typedef trio_ulonglong_t trio_uintmax_t;
-typedef __int8 trio_int8_t;
-typedef __int16 trio_int16_t;
-typedef __int32 trio_int32_t;
-typedef __int64 trio_int64_t;
-#else
-typedef trio_longlong_t trio_intmax_t;
-typedef trio_ulonglong_t trio_uintmax_t;
-# if defined(TRIO_INT8_T)
-typedef TRIO_INT8_T trio_int8_t;
-# else
-typedef TRIO_SIGNED char trio_int8_t;
-# endif
-# if defined(TRIO_INT16_T)
-typedef TRIO_INT16_T trio_int16_t;
-# else
-typedef TRIO_SIGNED short trio_int16_t;
-# endif
-# if defined(TRIO_INT32_T)
-typedef TRIO_INT32_T trio_int32_t;
-# else
-typedef TRIO_SIGNED int trio_int32_t;
-# endif
-# if defined(TRIO_INT64_T)
-typedef TRIO_INT64_T trio_int64_t;
-# else
-typedef trio_longlong_t trio_int64_t;
-# endif
-#endif
-
-#if (!(defined(TRIO_COMPILER_SUPPORTS_C99) \
- || defined(TRIO_COMPILER_SUPPORTS_UNIX01))) \
- && !defined(_WIN32_WCE)
-# define floorl(x) floor((double)(x))
-# define fmodl(x,y) fmod((double)(x),(double)(y))
-# define powl(x,y) pow((double)(x),(double)(y))
-#endif
-
-#define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
-
-/*************************************************************************
- * Internal Definitions
- */
-
-#ifndef DECIMAL_DIG
-# define DECIMAL_DIG DBL_DIG
-#endif
-
-/* Long double sizes */
-#ifdef LDBL_DIG
-# define MAX_MANTISSA_DIGITS LDBL_DIG
-# define MAX_EXPONENT_DIGITS 4
-# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
-#else
-# define MAX_MANTISSA_DIGITS DECIMAL_DIG
-# define MAX_EXPONENT_DIGITS 3
-# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
-#endif
-
-#if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
-# undef LDBL_DIG
-# undef LDBL_MANT_DIG
-# undef LDBL_EPSILON
-# define LDBL_DIG DBL_DIG
-# define LDBL_MANT_DIG DBL_MANT_DIG
-# define LDBL_EPSILON DBL_EPSILON
-#endif
-
-/* The maximal number of digits is for base 2 */
-#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)
-/* The width of a pointer. The number of bits in a hex digit is 4 */
-#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)
-
-/* Infinite and Not-A-Number for floating-point */
-#define INFINITE_LOWER "inf"
-#define INFINITE_UPPER "INF"
-#define LONG_INFINITE_LOWER "infinite"
-#define LONG_INFINITE_UPPER "INFINITE"
-#define NAN_LOWER "nan"
-#define NAN_UPPER "NAN"
-
-#if !defined(HAVE_ISASCII) && !defined(isascii)
-#ifndef __VMS
-# define isascii(x) ((unsigned int)(x) < 128)
-#endif
-#endif
-
-/* Various constants */
-enum {
- TYPE_PRINT = 1,
- TYPE_SCAN = 2,
-
- /* Flags. FLAGS_LAST must be less than ULONG_MAX */
- FLAGS_NEW = 0,
- FLAGS_STICKY = 1,
- FLAGS_SPACE = 2 * FLAGS_STICKY,
- FLAGS_SHOWSIGN = 2 * FLAGS_SPACE,
- FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN,
- FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST,
- FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE,
- FLAGS_SHORTSHORT = 2 * FLAGS_SHORT,
- FLAGS_LONG = 2 * FLAGS_SHORTSHORT,
- FLAGS_QUAD = 2 * FLAGS_LONG,
- FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD,
- FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE,
- FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T,
- FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T,
- FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T,
- FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING,
- FLAGS_UPPER = 2 * FLAGS_UNSIGNED,
- FLAGS_WIDTH = 2 * FLAGS_UPPER,
- FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH,
- FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER,
- FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION,
- FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER,
- FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE,
- FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER,
- FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E,
- FLAGS_QUOTE = 2 * FLAGS_FLOAT_G,
- FLAGS_WIDECHAR = 2 * FLAGS_QUOTE,
- FLAGS_ALLOC = 2 * FLAGS_WIDECHAR,
- FLAGS_IGNORE = 2 * FLAGS_ALLOC,
- FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE,
- FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER,
- FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER,
- FLAGS_LAST = FLAGS_FIXED_SIZE,
- /* Reused flags */
- FLAGS_EXCLUDE = FLAGS_SHORT,
- FLAGS_USER_DEFINED = FLAGS_IGNORE,
- FLAGS_ROUNDING = FLAGS_INTMAX_T,
- /* Compounded flags */
- FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T,
- FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT,
-
- NO_POSITION = -1,
- NO_WIDTH = 0,
- NO_PRECISION = -1,
- NO_SIZE = -1,
-
- /* Do not change these */
- NO_BASE = -1,
- MIN_BASE = 2,
- MAX_BASE = 36,
- BASE_BINARY = 2,
- BASE_OCTAL = 8,
- BASE_DECIMAL = 10,
- BASE_HEX = 16,
-
- /* Maximal number of allowed parameters */
- MAX_PARAMETERS = 64,
- /* Maximal number of characters in class */
- MAX_CHARACTER_CLASS = UCHAR_MAX + 1,
-
- /* Maximal string lengths for user-defined specifiers */
- MAX_USER_NAME = 64,
- MAX_USER_DATA = 256,
-
- /* Maximal length of locale separator strings */
- MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX,
- /* Maximal number of integers in grouping */
- MAX_LOCALE_GROUPS = 64,
-
- /* Initial size of asprintf buffer */
- DYNAMIC_START_SIZE = 32
-};
-
-#define NO_GROUPING ((int)CHAR_MAX)
-
-/* Fundamental formatting parameter types */
-#define FORMAT_UNKNOWN 0
-#define FORMAT_INT 1
-#define FORMAT_DOUBLE 2
-#define FORMAT_CHAR 3
-#define FORMAT_STRING 4
-#define FORMAT_POINTER 5
-#define FORMAT_COUNT 6
-#define FORMAT_PARAMETER 7
-#define FORMAT_GROUP 8
-#if TRIO_GNU
-# define FORMAT_ERRNO 9
-#endif
-#if TRIO_EXTENSION
-# define FORMAT_USER_DEFINED 10
-#endif
-
-/* Character constants */
-#define CHAR_IDENTIFIER '%'
-#define CHAR_BACKSLASH '\\'
-#define CHAR_QUOTE '\"'
-#define CHAR_ADJUST ' '
-
-/* Character class expressions */
-#define CLASS_ALNUM "[:alnum:]"
-#define CLASS_ALPHA "[:alpha:]"
-#define CLASS_BLANK "[:blank:]"
-#define CLASS_CNTRL "[:cntrl:]"
-#define CLASS_DIGIT "[:digit:]"
-#define CLASS_GRAPH "[:graph:]"
-#define CLASS_LOWER "[:lower:]"
-#define CLASS_PRINT "[:print:]"
-#define CLASS_PUNCT "[:punct:]"
-#define CLASS_SPACE "[:space:]"
-#define CLASS_UPPER "[:upper:]"
-#define CLASS_XDIGIT "[:xdigit:]"
-
-/*
- * SPECIFIERS:
- *
- *
- * a Hex-float
- * A Hex-float
- * c Character
- * C Widechar character (wint_t)
- * d Decimal
- * e Float
- * E Float
- * F Float
- * F Float
- * g Float
- * G Float
- * i Integer
- * m Error message
- * n Count
- * o Octal
- * p Pointer
- * s String
- * S Widechar string (wchar_t *)
- * u Unsigned
- * x Hex
- * X Hex
- * [] Group
- * <> User-defined
- *
- * Reserved:
- *
- * D Binary Coded Decimal %D(length,precision) (OS/390)
- */
-#define SPECIFIER_CHAR 'c'
-#define SPECIFIER_STRING 's'
-#define SPECIFIER_DECIMAL 'd'
-#define SPECIFIER_INTEGER 'i'
-#define SPECIFIER_UNSIGNED 'u'
-#define SPECIFIER_OCTAL 'o'
-#define SPECIFIER_HEX 'x'
-#define SPECIFIER_HEX_UPPER 'X'
-#define SPECIFIER_FLOAT_E 'e'
-#define SPECIFIER_FLOAT_E_UPPER 'E'
-#define SPECIFIER_FLOAT_F 'f'
-#define SPECIFIER_FLOAT_F_UPPER 'F'
-#define SPECIFIER_FLOAT_G 'g'
-#define SPECIFIER_FLOAT_G_UPPER 'G'
-#define SPECIFIER_POINTER 'p'
-#define SPECIFIER_GROUP '['
-#define SPECIFIER_UNGROUP ']'
-#define SPECIFIER_COUNT 'n'
-#if TRIO_UNIX98
-# define SPECIFIER_CHAR_UPPER 'C'
-# define SPECIFIER_STRING_UPPER 'S'
-#endif
-#if TRIO_C99
-# define SPECIFIER_HEXFLOAT 'a'
-# define SPECIFIER_HEXFLOAT_UPPER 'A'
-#endif
-#if TRIO_GNU
-# define SPECIFIER_ERRNO 'm'
-#endif
-#if TRIO_EXTENSION
-# define SPECIFIER_BINARY 'b'
-# define SPECIFIER_BINARY_UPPER 'B'
-# define SPECIFIER_USER_DEFINED_BEGIN '<'
-# define SPECIFIER_USER_DEFINED_END '>'
-# define SPECIFIER_USER_DEFINED_SEPARATOR ':'
-#endif
-
-/*
- * QUALIFIERS:
- *
- *
- * Numbers = d,i,o,u,x,X
- * Float = a,A,e,E,f,F,g,G
- * String = s
- * Char = c
- *
- *
- * 9$ Position
- * Use the 9th parameter. 9 can be any number between 1 and
- * the maximal argument
- *
- * 9 Width
- * Set width to 9. 9 can be any number, but must not be postfixed
- * by '$'
- *
- * h Short
- * Numbers:
- * (unsigned) short int
- *
- * hh Short short
- * Numbers:
- * (unsigned) char
- *
- * l Long
- * Numbers:
- * (unsigned) long int
- * String:
- * as the S specifier
- * Char:
- * as the C specifier
- *
- * ll Long Long
- * Numbers:
- * (unsigned) long long int
- *
- * L Long Double
- * Float
- * long double
- *
- * # Alternative
- * Float:
- * Decimal-point is always present
- * String:
- * non-printable characters are handled as \number
- *
- * Spacing
- *
- * + Sign
- *
- * - Alignment
- *
- * . Precision
- *
- * * Parameter
- * print: use parameter
- * scan: no parameter (ignore)
- *
- * q Quad
- *
- * Z size_t
- *
- * w Widechar
- *
- * ' Thousands/quote
- * Numbers:
- * Integer part grouped in thousands
- * Binary numbers:
- * Number grouped in nibbles (4 bits)
- * String:
- * Quoted string
- *
- * j intmax_t
- * t prtdiff_t
- * z size_t
- *
- * ! Sticky
- * @ Parameter (for both print and scan)
- *
- * I n-bit Integer
- * Numbers:
- * The following options exists
- * I8 = 8-bit integer
- * I16 = 16-bit integer
- * I32 = 32-bit integer
- * I64 = 64-bit integer
- */
-#define QUALIFIER_POSITION '$'
-#define QUALIFIER_SHORT 'h'
-#define QUALIFIER_LONG 'l'
-#define QUALIFIER_LONG_UPPER 'L'
-#define QUALIFIER_ALTERNATIVE '#'
-#define QUALIFIER_SPACE ' '
-#define QUALIFIER_PLUS '+'
-#define QUALIFIER_MINUS '-'
-#define QUALIFIER_DOT '.'
-#define QUALIFIER_STAR '*'
-#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */
-#if TRIO_C99
-# define QUALIFIER_SIZE_T 'z'
-# define QUALIFIER_PTRDIFF_T 't'
-# define QUALIFIER_INTMAX_T 'j'
-#endif
-#if TRIO_BSD || TRIO_GNU
-# define QUALIFIER_QUAD 'q'
-#endif
-#if TRIO_GNU
-# define QUALIFIER_SIZE_T_UPPER 'Z'
-#endif
-#if TRIO_MISC
-# define QUALIFIER_WIDECHAR 'w'
-#endif
-#if TRIO_MICROSOFT
-# define QUALIFIER_FIXED_SIZE 'I'
-#endif
-#if TRIO_EXTENSION
-# define QUALIFIER_QUOTE '\''
-# define QUALIFIER_STICKY '!'
-# define QUALIFIER_VARSIZE '&' /* This should remain undocumented */
-# define QUALIFIER_PARAM '@' /* Experimental */
-# define QUALIFIER_COLON ':' /* For scanlists */
-# define QUALIFIER_EQUAL '=' /* For scanlists */
-# define QUALIFIER_ROUNDING_UPPER 'R'
-#endif
-
-
-/*************************************************************************
- *
- * Internal Structures
- *
- *************************************************************************/
-
-/* Parameters */
-typedef struct {
- /* An indication of which entry in the data union is used */
- int type;
- /* The flags */
- trio_flags_t flags;
- /* The width qualifier */
- int width;
- /* The precision qualifier */
- int precision;
- /* The base qualifier */
- int base;
- /* The size for the variable size qualifier */
- int varsize;
- /* The marker of the end of the specifier */
- int indexAfterSpecifier;
- /* The data from the argument list */
- union {
- char *string;
-#if TRIO_WIDECHAR
- trio_wchar_t *wstring;
-#endif
- trio_pointer_t pointer;
- union {
- trio_intmax_t as_signed;
- trio_uintmax_t as_unsigned;
- } number;
- double doubleNumber;
- double *doublePointer;
- trio_long_double_t longdoubleNumber;
- trio_long_double_t *longdoublePointer;
- int errorNumber;
- } data;
- /* For the user-defined specifier */
- char user_name[MAX_USER_NAME];
- char user_data[MAX_USER_DATA];
-} trio_parameter_t;
-
-/* Container for customized functions */
-typedef struct {
- union {
- trio_outstream_t out;
- trio_instream_t in;
- } stream;
- trio_pointer_t closure;
-} trio_custom_t;
-
-/* General trio "class" */
-typedef struct _trio_class_t {
- /*
- * The function to write characters to a stream.
- */
- void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int));
- /*
- * The function to read characters from a stream.
- */
- void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *));
- /*
- * The current location in the stream.
- */
- trio_pointer_t location;
- /*
- * The character currently being processed.
- */
- int current;
- /*
- * The number of characters that would have been written/read
- * if there had been sufficient space.
- */
- int processed;
- /*
- * The number of characters that are actually written/read.
- * Processed and committed will only differ for the *nprintf
- * and *nscanf functions.
- */
- int committed;
- /*
- * The upper limit of characters that may be written/read.
- */
- int max;
- /*
- * The last output error that was detected.
- */
- int error;
-} trio_class_t;
-
-/* References (for user-defined callbacks) */
-typedef struct _trio_reference_t {
- trio_class_t *data;
- trio_parameter_t *parameter;
-} trio_reference_t;
-
-/* Registered entries (for user-defined callbacks) */
-typedef struct _trio_userdef_t {
- struct _trio_userdef_t *next;
- trio_callback_t callback;
- char *name;
-} trio_userdef_t;
-
-/*************************************************************************
- *
- * Internal Variables
- *
- *************************************************************************/
-
-static TRIO_CONST char rcsid[] = "@(#)$Id$";
-
-/*
- * Need this to workaround a parser bug in HP C/iX compiler that fails
- * to resolves macro definitions that includes type 'long double',
- * e.g: va_arg(arg_ptr, long double)
- */
-#if defined(TRIO_PLATFORM_MPEIX)
-static TRIO_CONST trio_long_double_t ___dummy_long_double = 0;
-#endif
-
-static TRIO_CONST char internalNullString[] = "(nil)";
-
-#if defined(USE_LOCALE)
-static struct lconv *internalLocaleValues = NULL;
-#endif
-
-/*
- * UNIX98 says "in a locale where the radix character is not defined,
- * the radix character defaults to a period (.)"
- */
-static int internalDecimalPointLength = 1;
-static int internalThousandSeparatorLength = 1;
-static char internalDecimalPoint = '.';
-static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";
-static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";
-static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };
-
-static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-static BOOLEAN_T internalDigitsUnconverted = TRUE;
-static int internalDigitArray[128];
-#if TRIO_EXTENSION
-static BOOLEAN_T internalCollationUnconverted = TRUE;
-static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];
-#endif
-
-#if TRIO_EXTENSION
-static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;
-static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;
-static trio_userdef_t *internalUserDef = NULL;
-#endif
-
-
-/*************************************************************************
- *
- * Internal Functions
- *
- ************************************************************************/
-
-#if defined(TRIO_MINIMAL)
-# define TRIO_STRING_PUBLIC static
-# include "triostr.c"
-#endif /* defined(TRIO_MINIMAL) */
-
-/*************************************************************************
- * TrioIsQualifier
- *
- * Description:
- * Remember to add all new qualifiers to this function.
- * QUALIFIER_POSITION must not be added.
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioIsQualifier
-TRIO_ARGS1((character),
- TRIO_CONST char character)
-{
- /* QUALIFIER_POSITION is not included */
- switch (character)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case QUALIFIER_PLUS:
- case QUALIFIER_MINUS:
- case QUALIFIER_SPACE:
- case QUALIFIER_DOT:
- case QUALIFIER_STAR:
- case QUALIFIER_ALTERNATIVE:
- case QUALIFIER_SHORT:
- case QUALIFIER_LONG:
- case QUALIFIER_LONG_UPPER:
- case QUALIFIER_CIRCUMFLEX:
-#if defined(QUALIFIER_SIZE_T)
- case QUALIFIER_SIZE_T:
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- case QUALIFIER_PTRDIFF_T:
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- case QUALIFIER_INTMAX_T:
-#endif
-#if defined(QUALIFIER_QUAD)
- case QUALIFIER_QUAD:
-#endif
-#if defined(QUALIFIER_SIZE_T_UPPER)
- case QUALIFIER_SIZE_T_UPPER:
-#endif
-#if defined(QUALIFIER_WIDECHAR)
- case QUALIFIER_WIDECHAR:
-#endif
-#if defined(QUALIFIER_QUOTE)
- case QUALIFIER_QUOTE:
-#endif
-#if defined(QUALIFIER_STICKY)
- case QUALIFIER_STICKY:
-#endif
-#if defined(QUALIFIER_VARSIZE)
- case QUALIFIER_VARSIZE:
-#endif
-#if defined(QUALIFIER_PARAM)
- case QUALIFIER_PARAM:
-#endif
-#if defined(QUALIFIER_FIXED_SIZE)
- case QUALIFIER_FIXED_SIZE:
-#endif
-#if defined(QUALIFIER_ROUNDING_UPPER)
- case QUALIFIER_ROUNDING_UPPER:
-#endif
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-/*************************************************************************
- * TrioSetLocale
- */
-#if defined(USE_LOCALE)
-TRIO_PRIVATE void
-TrioSetLocale(TRIO_NOARGS)
-{
- internalLocaleValues = (struct lconv *)localeconv();
- if (internalLocaleValues)
- {
- if ((internalLocaleValues->decimal_point) &&
- (internalLocaleValues->decimal_point[0] != NIL))
- {
- internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point);
- if (internalDecimalPointLength == 1)
- {
- internalDecimalPoint = internalLocaleValues->decimal_point[0];
- }
- else
- {
- internalDecimalPoint = NIL;
- trio_copy_max(internalDecimalPointString,
- sizeof(internalDecimalPointString),
- internalLocaleValues->decimal_point);
- }
- }
- if ((internalLocaleValues->thousands_sep) &&
- (internalLocaleValues->thousands_sep[0] != NIL))
- {
- trio_copy_max(internalThousandSeparator,
- sizeof(internalThousandSeparator),
- internalLocaleValues->thousands_sep);
- internalThousandSeparatorLength = trio_length(internalThousandSeparator);
- }
- if ((internalLocaleValues->grouping) &&
- (internalLocaleValues->grouping[0] != NIL))
- {
- trio_copy_max(internalGrouping,
- sizeof(internalGrouping),
- internalLocaleValues->grouping);
- }
- }
-}
-#endif /* defined(USE_LOCALE) */
-
-TRIO_PRIVATE int
-TrioCalcThousandSeparatorLength
-TRIO_ARGS1((digits),
- int digits)
-{
-#if TRIO_EXTENSION
- int count = 0;
- int step = NO_GROUPING;
- char *groupingPointer = internalGrouping;
-
- while (digits > 0)
- {
- if (*groupingPointer == CHAR_MAX)
- {
- /* Disable grouping */
- break; /* while */
- }
- else if (*groupingPointer == 0)
- {
- /* Repeat last group */
- if (step == NO_GROUPING)
- {
- /* Error in locale */
- break; /* while */
- }
- }
- else
- {
- step = *groupingPointer++;
- }
- if (digits > step)
- count += internalThousandSeparatorLength;
- digits -= step;
- }
- return count;
-#else
- return 0;
-#endif
-}
-
-TRIO_PRIVATE BOOLEAN_T
-TrioFollowedBySeparator
-TRIO_ARGS1((position),
- int position)
-{
-#if TRIO_EXTENSION
- int step = 0;
- char *groupingPointer = internalGrouping;
-
- position--;
- if (position == 0)
- return FALSE;
- while (position > 0)
- {
- if (*groupingPointer == CHAR_MAX)
- {
- /* Disable grouping */
- break; /* while */
- }
- else if (*groupingPointer != 0)
- {
- step = *groupingPointer++;
- }
- if (step == 0)
- break;
- position -= step;
- }
- return (position == 0);
-#else
- return FALSE;
-#endif
-}
-
-/*************************************************************************
- * TrioGetPosition
- *
- * Get the %n$ position.
- */
-TRIO_PRIVATE int
-TrioGetPosition
-TRIO_ARGS2((format, indexPointer),
- TRIO_CONST char *format,
- int *indexPointer)
-{
-#if TRIO_UNIX98
- char *tmpformat;
- int number = 0;
- int index = *indexPointer;
-
- number = (int)trio_to_long(&format[index], &tmpformat, BASE_DECIMAL);
- index = (int)(tmpformat - format);
- if ((number != 0) && (QUALIFIER_POSITION == format[index++]))
- {
- *indexPointer = index;
- /*
- * number is decreased by 1, because n$ starts from 1, whereas
- * the array it is indexing starts from 0.
- */
- return number - 1;
- }
-#endif
- return NO_POSITION;
-}
-
-#if TRIO_EXTENSION
-/*************************************************************************
- * TrioFindNamespace
- *
- * Find registered user-defined specifier.
- * The prev argument is used for optimization only.
- */
-TRIO_PRIVATE trio_userdef_t *
-TrioFindNamespace
-TRIO_ARGS2((name, prev),
- TRIO_CONST char *name,
- trio_userdef_t **prev)
-{
- trio_userdef_t *def;
-
- if (internalEnterCriticalRegion)
- (void)internalEnterCriticalRegion(NULL);
-
- for (def = internalUserDef; def; def = def->next)
- {
- /* Case-sensitive string comparison */
- if (trio_equal_case(def->name, name))
- break;
-
- if (prev)
- *prev = def;
- }
-
- if (internalLeaveCriticalRegion)
- (void)internalLeaveCriticalRegion(NULL);
-
- return def;
-}
-#endif
-
-/*************************************************************************
- * TrioPower
- *
- * Description:
- * Calculate pow(base, exponent), where number and exponent are integers.
- */
-TRIO_PRIVATE trio_long_double_t
-TrioPower
-TRIO_ARGS2((number, exponent),
- int number,
- int exponent)
-{
- trio_long_double_t result;
-
- if (number == 10)
- {
- switch (exponent)
- {
- /* Speed up calculation of common cases */
- case 0:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1);
- break;
- case 1:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0);
- break;
- case 2:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1);
- break;
- case 3:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2);
- break;
- case 4:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3);
- break;
- case 5:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4);
- break;
- case 6:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5);
- break;
- case 7:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6);
- break;
- case 8:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7);
- break;
- case 9:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8);
- break;
- default:
- result = powl((trio_long_double_t)number,
- (trio_long_double_t)exponent);
- break;
- }
- }
- else
- {
- return powl((trio_long_double_t)number, (trio_long_double_t)exponent);
- }
- return result;
-}
-
-/*************************************************************************
- * TrioLogarithm
- */
-TRIO_PRIVATE double
-TrioLogarithm
-TRIO_ARGS2((number, base),
- double number,
- int base)
-{
- double result;
-
- if (number <= 0.0)
- {
- /* xlC crashes on log(0) */
- result = (number == 0.0) ? trio_ninf() : trio_nan();
- }
- else
- {
- if (base == 10)
- {
- result = log10(number);
- }
- else
- {
- result = log10(number) / log10((double)base);
- }
- }
- return result;
-}
-
-/*************************************************************************
- * TrioLogarithmBase
- */
-TRIO_PRIVATE double
-TrioLogarithmBase
-TRIO_ARGS1((base),
- int base)
-{
- switch (base)
- {
- case BASE_BINARY : return 1.0;
- case BASE_OCTAL : return 3.0;
- case BASE_DECIMAL: return 3.321928094887362345;
- case BASE_HEX : return 4.0;
- default : return TrioLogarithm((double)base, 2);
- }
-}
-
-/*************************************************************************
- * TrioParse
- *
- * Description:
- * Parse the format string
- */
-TRIO_PRIVATE int
-TrioParse
-TRIO_ARGS5((type, format, parameters, arglist, argarray),
- int type,
- TRIO_CONST char *format,
- trio_parameter_t *parameters,
- TRIO_VA_LIST_PTR arglist,
- trio_pointer_t *argarray)
-{
- /* Count the number of times a parameter is referenced */
- unsigned short usedEntries[MAX_PARAMETERS];
- /* Parameter counters */
- int parameterPosition;
- int currentParam;
- int maxParam = -1;
- /* Utility variables */
- trio_flags_t flags;
- int width;
- int precision;
- int varsize;
- int base;
- int index; /* Index into formatting string */
- int dots; /* Count number of dots in modifier part */
- BOOLEAN_T positional; /* Does the specifier have a positional? */
- BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */
- /*
- * indices specifies the order in which the parameters must be
- * read from the va_args (this is necessary to handle positionals)
- */
- int indices[MAX_PARAMETERS];
- int pos = 0;
- /* Various variables */
- char ch;
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- int charlen;
-#endif
- int save_errno;
- int i = -1;
- int num;
- char *tmpformat;
-
- /* One and only one of arglist and argarray must be used */
- assert((arglist != NULL) ^ (argarray != NULL));
-
- /*
- * The 'parameters' array is not initialized, but we need to
- * know which entries we have used.
- */
- memset(usedEntries, 0, sizeof(usedEntries));
-
- save_errno = errno;
- index = 0;
- parameterPosition = 0;
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- while (format[index])
- {
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- if (! isascii(format[index]))
- {
- /*
- * Multibyte characters cannot be legal specifiers or
- * modifiers, so we skip over them.
- */
- charlen = mblen(&format[index], MB_LEN_MAX);
- index += (charlen > 0) ? charlen : 1;
- continue; /* while */
- }
-#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
- if (CHAR_IDENTIFIER == format[index++])
- {
- if (CHAR_IDENTIFIER == format[index])
- {
- index++;
- continue; /* while */
- }
-
- flags = FLAGS_NEW;
- dots = 0;
- currentParam = TrioGetPosition(format, &index);
- positional = (NO_POSITION != currentParam);
- if (!positional)
- {
- /* We have no positional, get the next counter */
- currentParam = parameterPosition;
- }
- if(currentParam >= MAX_PARAMETERS)
- {
- /* Bail out completely to make the error more obvious */
- return TRIO_ERROR_RETURN(TRIO_ETOOMANY, index);
- }
-
- if (currentParam > maxParam)
- maxParam = currentParam;
-
- /* Default values */
- width = NO_WIDTH;
- precision = NO_PRECISION;
- base = NO_BASE;
- varsize = NO_SIZE;
-
- while (TrioIsQualifier(format[index]))
- {
- ch = format[index++];
-
- switch (ch)
- {
- case QUALIFIER_SPACE:
- flags |= FLAGS_SPACE;
- break;
-
- case QUALIFIER_PLUS:
- flags |= FLAGS_SHOWSIGN;
- break;
-
- case QUALIFIER_MINUS:
- flags |= FLAGS_LEFTADJUST;
- flags &= ~FLAGS_NILPADDING;
- break;
-
- case QUALIFIER_ALTERNATIVE:
- flags |= FLAGS_ALTERNATIVE;
- break;
-
- case QUALIFIER_DOT:
- if (dots == 0) /* Precision */
- {
- dots++;
-
- /* Skip if no precision */
- if (QUALIFIER_DOT == format[index])
- break;
-
- /* After the first dot we have the precision */
- flags |= FLAGS_PRECISION;
- if ((QUALIFIER_STAR == format[index])
-#if defined(QUALIFIER_PARAM)
- || (QUALIFIER_PARAM == format[index])
-#endif
- )
- {
- index++;
- flags |= FLAGS_PRECISION_PARAMETER;
-
- precision = TrioGetPosition(format, &index);
- if (precision == NO_POSITION)
- {
- parameterPosition++;
- if (positional)
- precision = parameterPosition;
- else
- {
- precision = currentParam;
- currentParam = precision + 1;
- }
- }
- else
- {
- if (! positional)
- currentParam = precision + 1;
- if (width > maxParam)
- maxParam = precision;
- }
- if (currentParam > maxParam)
- maxParam = currentParam;
- }
- else
- {
- precision = trio_to_long(&format[index],
- &tmpformat,
- BASE_DECIMAL);
- index = (int)(tmpformat - format);
- }
- }
- else if (dots == 1) /* Base */
- {
- dots++;
-
- /* After the second dot we have the base */
- flags |= FLAGS_BASE;
- if ((QUALIFIER_STAR == format[index])
-#if defined(QUALIFIER_PARAM)
- || (QUALIFIER_PARAM == format[index])
-#endif
- )
- {
- index++;
- flags |= FLAGS_BASE_PARAMETER;
- base = TrioGetPosition(format, &index);
- if (base == NO_POSITION)
- {
- parameterPosition++;
- if (positional)
- base = parameterPosition;
- else
- {
- base = currentParam;
- currentParam = base + 1;
- }
- }
- else
- {
- if (! positional)
- currentParam = base + 1;
- if (base > maxParam)
- maxParam = base;
- }
- if (currentParam > maxParam)
- maxParam = currentParam;
- }
- else
- {
- base = trio_to_long(&format[index],
- &tmpformat,
- BASE_DECIMAL);
- if (base > MAX_BASE)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- index = (int)(tmpformat - format);
- }
- }
- else
- {
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- break; /* QUALIFIER_DOT */
-
-#if defined(QUALIFIER_PARAM)
- case QUALIFIER_PARAM:
- type = TYPE_PRINT;
- /* FALLTHROUGH */
-#endif
- case QUALIFIER_STAR:
- /* This has different meanings for print and scan */
- if (TYPE_PRINT == type)
- {
- /* Read with from parameter */
- flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);
- width = TrioGetPosition(format, &index);
- if (width == NO_POSITION)
- {
- parameterPosition++;
- if (positional)
- width = parameterPosition;
- else
- {
- width = currentParam;
- currentParam = width + 1;
- }
- }
- else
- {
- if (! positional)
- currentParam = width + 1;
- if (width > maxParam)
- maxParam = width;
- }
- if (currentParam > maxParam)
- maxParam = currentParam;
- }
- else
- {
- /* Scan, but do not store result */
- flags |= FLAGS_IGNORE;
- }
-
- break; /* QUALIFIER_STAR */
-
- case '0':
- if (! (flags & FLAGS_LEFTADJUST))
- flags |= FLAGS_NILPADDING;
- /* FALLTHROUGH */
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- flags |= FLAGS_WIDTH;
- /* &format[index - 1] is used to "rewind" the read
- * character from format
- */
- width = trio_to_long(&format[index - 1],
- &tmpformat,
- BASE_DECIMAL);
- index = (int)(tmpformat - format);
- break;
-
- case QUALIFIER_SHORT:
- if (flags & FLAGS_SHORTSHORT)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- else if (flags & FLAGS_SHORT)
- flags |= FLAGS_SHORTSHORT;
- else
- flags |= FLAGS_SHORT;
- break;
-
- case QUALIFIER_LONG:
- if (flags & FLAGS_QUAD)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- else if (flags & FLAGS_LONG)
- flags |= FLAGS_QUAD;
- else
- flags |= FLAGS_LONG;
- break;
-
- case QUALIFIER_LONG_UPPER:
- flags |= FLAGS_LONGDOUBLE;
- break;
-
-#if defined(QUALIFIER_SIZE_T)
- case QUALIFIER_SIZE_T:
- flags |= FLAGS_SIZE_T;
- /* Modify flags for later truncation of number */
- if (sizeof(size_t) == sizeof(trio_ulonglong_t))
- flags |= FLAGS_QUAD;
- else if (sizeof(size_t) == sizeof(long))
- flags |= FLAGS_LONG;
- break;
-#endif
-
-#if defined(QUALIFIER_PTRDIFF_T)
- case QUALIFIER_PTRDIFF_T:
- flags |= FLAGS_PTRDIFF_T;
- if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))
- flags |= FLAGS_QUAD;
- else if (sizeof(ptrdiff_t) == sizeof(long))
- flags |= FLAGS_LONG;
- break;
-#endif
-
-#if defined(QUALIFIER_INTMAX_T)
- case QUALIFIER_INTMAX_T:
- flags |= FLAGS_INTMAX_T;
- if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))
- flags |= FLAGS_QUAD;
- else if (sizeof(trio_intmax_t) == sizeof(long))
- flags |= FLAGS_LONG;
- break;
-#endif
-
-#if defined(QUALIFIER_QUAD)
- case QUALIFIER_QUAD:
- flags |= FLAGS_QUAD;
- break;
-#endif
-
-#if defined(QUALIFIER_FIXED_SIZE)
- case QUALIFIER_FIXED_SIZE:
- if (flags & FLAGS_FIXED_SIZE)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
-
- if (flags & (FLAGS_ALL_SIZES | FLAGS_LONGDOUBLE |
- FLAGS_WIDECHAR | FLAGS_VARSIZE_PARAMETER))
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
-
- if ((format[index] == '6') &&
- (format[index + 1] == '4'))
- {
- varsize = sizeof(trio_int64_t);
- index += 2;
- }
- else if ((format[index] == '3') &&
- (format[index + 1] == '2'))
- {
- varsize = sizeof(trio_int32_t);
- index += 2;
- }
- else if ((format[index] == '1') &&
- (format[index + 1] == '6'))
- {
- varsize = sizeof(trio_int16_t);
- index += 2;
- }
- else if (format[index] == '8')
- {
- varsize = sizeof(trio_int8_t);
- index++;
- }
- else
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
-
- flags |= FLAGS_FIXED_SIZE;
- break;
-#endif
-
-#if defined(QUALIFIER_WIDECHAR)
- case QUALIFIER_WIDECHAR:
- flags |= FLAGS_WIDECHAR;
- break;
-#endif
-
-#if defined(QUALIFIER_SIZE_T_UPPER)
- case QUALIFIER_SIZE_T_UPPER:
- break;
-#endif
-
-#if defined(QUALIFIER_QUOTE)
- case QUALIFIER_QUOTE:
- flags |= FLAGS_QUOTE;
- break;
-#endif
-
-#if defined(QUALIFIER_STICKY)
- case QUALIFIER_STICKY:
- flags |= FLAGS_STICKY;
- gotSticky = TRUE;
- break;
-#endif
-
-#if defined(QUALIFIER_VARSIZE)
- case QUALIFIER_VARSIZE:
- flags |= FLAGS_VARSIZE_PARAMETER;
- parameterPosition++;
- if (positional)
- varsize = parameterPosition;
- else
- {
- varsize = currentParam;
- currentParam = varsize + 1;
- }
- if (currentParam > maxParam)
- maxParam = currentParam;
- break;
-#endif
-
-#if defined(QUALIFIER_ROUNDING_UPPER)
- case QUALIFIER_ROUNDING_UPPER:
- flags |= FLAGS_ROUNDING;
- break;
-#endif
-
- default:
- /* Bail out completely to make the error more obvious */
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- } /* while qualifier */
-
- /*
- * Parameters only need the type and value. The value is
- * read later.
- */
- if (flags & FLAGS_WIDTH_PARAMETER)
- {
- usedEntries[width] += 1;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[width] = pos;
- width = pos++;
- }
- if (flags & FLAGS_PRECISION_PARAMETER)
- {
- usedEntries[precision] += 1;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[precision] = pos;
- precision = pos++;
- }
- if (flags & FLAGS_BASE_PARAMETER)
- {
- usedEntries[base] += 1;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[base] = pos;
- base = pos++;
- }
- if (flags & FLAGS_VARSIZE_PARAMETER)
- {
- usedEntries[varsize] += 1;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[varsize] = pos;
- varsize = pos++;
- }
-
- indices[currentParam] = pos;
-
- switch (format[index++])
- {
-#if defined(SPECIFIER_CHAR_UPPER)
- case SPECIFIER_CHAR_UPPER:
- flags |= FLAGS_WIDECHAR;
- /* FALLTHROUGH */
-#endif
- case SPECIFIER_CHAR:
- if (flags & FLAGS_LONG)
- flags |= FLAGS_WIDECHAR;
- else if (flags & FLAGS_SHORT)
- flags &= ~FLAGS_WIDECHAR;
- parameters[pos].type = FORMAT_CHAR;
- break;
-
-#if defined(SPECIFIER_STRING_UPPER)
- case SPECIFIER_STRING_UPPER:
- flags |= FLAGS_WIDECHAR;
- /* FALLTHROUGH */
-#endif
- case SPECIFIER_STRING:
- if (flags & FLAGS_LONG)
- flags |= FLAGS_WIDECHAR;
- else if (flags & FLAGS_SHORT)
- flags &= ~FLAGS_WIDECHAR;
- parameters[pos].type = FORMAT_STRING;
- break;
-
- case SPECIFIER_GROUP:
- if (TYPE_SCAN == type)
- {
- int depth = 1;
- parameters[pos].type = FORMAT_GROUP;
- if (format[index] == QUALIFIER_CIRCUMFLEX)
- index++;
- if (format[index] == SPECIFIER_UNGROUP)
- index++;
- if (format[index] == QUALIFIER_MINUS)
- index++;
- /* Skip nested brackets */
- while (format[index] != NIL)
- {
- if (format[index] == SPECIFIER_GROUP)
- {
- depth++;
- }
- else if (format[index] == SPECIFIER_UNGROUP)
- {
- if (--depth <= 0)
- {
- index++;
- break;
- }
- }
- index++;
- }
- }
- break;
-
- case SPECIFIER_INTEGER:
- parameters[pos].type = FORMAT_INT;
- break;
-
- case SPECIFIER_UNSIGNED:
- flags |= FLAGS_UNSIGNED;
- parameters[pos].type = FORMAT_INT;
- break;
-
- case SPECIFIER_DECIMAL:
- /* Disable base modifier */
- flags &= ~FLAGS_BASE_PARAMETER;
- base = BASE_DECIMAL;
- parameters[pos].type = FORMAT_INT;
- break;
-
- case SPECIFIER_OCTAL:
- flags |= FLAGS_UNSIGNED;
- flags &= ~FLAGS_BASE_PARAMETER;
- base = BASE_OCTAL;
- parameters[pos].type = FORMAT_INT;
- break;
-
-#if defined(SPECIFIER_BINARY)
- case SPECIFIER_BINARY_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_BINARY:
- flags |= FLAGS_NILPADDING;
- flags &= ~FLAGS_BASE_PARAMETER;
- base = BASE_BINARY;
- parameters[pos].type = FORMAT_INT;
- break;
-#endif
-
- case SPECIFIER_HEX_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_HEX:
- flags |= FLAGS_UNSIGNED;
- flags &= ~FLAGS_BASE_PARAMETER;
- base = BASE_HEX;
- parameters[pos].type = FORMAT_INT;
- break;
-
- case SPECIFIER_FLOAT_E_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_FLOAT_E:
- flags |= FLAGS_FLOAT_E;
- parameters[pos].type = FORMAT_DOUBLE;
- break;
-
- case SPECIFIER_FLOAT_G_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_FLOAT_G:
- flags |= FLAGS_FLOAT_G;
- parameters[pos].type = FORMAT_DOUBLE;
- break;
-
- case SPECIFIER_FLOAT_F_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_FLOAT_F:
- parameters[pos].type = FORMAT_DOUBLE;
- break;
-
- case SPECIFIER_POINTER:
- if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
- flags |= FLAGS_QUAD;
- else if (sizeof(trio_pointer_t) == sizeof(long))
- flags |= FLAGS_LONG;
- parameters[pos].type = FORMAT_POINTER;
- break;
-
- case SPECIFIER_COUNT:
- parameters[pos].type = FORMAT_COUNT;
- break;
-
-#if defined(SPECIFIER_HEXFLOAT)
-# if defined(SPECIFIER_HEXFLOAT_UPPER)
- case SPECIFIER_HEXFLOAT_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
-# endif
- case SPECIFIER_HEXFLOAT:
- base = BASE_HEX;
- parameters[pos].type = FORMAT_DOUBLE;
- break;
-#endif
-
-#if defined(FORMAT_ERRNO)
- case SPECIFIER_ERRNO:
- parameters[pos].type = FORMAT_ERRNO;
- break;
-#endif
-
-#if defined(SPECIFIER_USER_DEFINED_BEGIN)
- case SPECIFIER_USER_DEFINED_BEGIN:
- {
- unsigned int max;
- int without_namespace = TRUE;
-
- parameters[pos].type = FORMAT_USER_DEFINED;
- parameters[pos].user_name[0] = NIL;
- tmpformat = (char *)&format[index];
-
- while ((ch = format[index]))
- {
- index++;
- if (ch == SPECIFIER_USER_DEFINED_END)
- {
- if (without_namespace)
- {
- /* We must get the handle first */
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].indexAfterSpecifier = index;
- parameters[pos].flags = FLAGS_USER_DEFINED;
- /* Adjust parameters for insertion of new one */
- pos++;
- usedEntries[currentParam] += 1;
- parameters[pos].type = FORMAT_USER_DEFINED;
- currentParam++;
- indices[currentParam] = pos;
- if (currentParam > maxParam)
- maxParam = currentParam;
- }
- /* Copy the user data */
- max = (unsigned int)(&format[index] - tmpformat);
- if (max > MAX_USER_DATA)
- max = MAX_USER_DATA;
- trio_copy_max(parameters[pos].user_data,
- max,
- tmpformat);
- break; /* while */
- }
- if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)
- {
- without_namespace = FALSE;
- /* Copy the namespace for later looking-up */
- max = (int)(&format[index] - tmpformat);
- if (max > MAX_USER_NAME)
- max = MAX_USER_NAME;
- trio_copy_max(parameters[pos].user_name,
- max,
- tmpformat);
- tmpformat = (char *)&format[index];
- }
- }
- if (ch != SPECIFIER_USER_DEFINED_END)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- break;
-#endif /* defined(SPECIFIER_USER_DEFINED_BEGIN) */
-
- default:
- /* Bail out completely to make the error more obvious */
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
-
- /* Count the number of times this entry has been used */
- usedEntries[currentParam] += 1;
-
- /* Find last sticky parameters */
- if (gotSticky && !(flags & FLAGS_STICKY))
- {
- for (i = pos - 1; i >= 0; i--)
- {
- if (parameters[i].type == FORMAT_PARAMETER)
- continue;
- if ((parameters[i].flags & FLAGS_STICKY) &&
- (parameters[i].type == parameters[pos].type))
- {
- /* Do not overwrite current qualifiers */
- flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY);
- if (width == NO_WIDTH)
- width = parameters[i].width;
- if (precision == NO_PRECISION)
- precision = parameters[i].precision;
- if (base == NO_BASE)
- base = parameters[i].base;
- break;
- }
- }
- }
-
- parameters[pos].indexAfterSpecifier = index;
- parameters[pos].flags = flags;
- parameters[pos].width = width;
- parameters[pos].precision = precision;
- parameters[pos].base = (base == NO_BASE) ? BASE_DECIMAL : base;
- parameters[pos].varsize = varsize;
- pos++;
-
- if (! positional)
- parameterPosition++;
-
- } /* if identifier */
-
- } /* while format characters left */
-
- for (num = 0; num <= maxParam; num++)
- {
- if (usedEntries[num] != 1)
- {
- if (usedEntries[num] == 0) /* gap detected */
- return TRIO_ERROR_RETURN(TRIO_EGAP, num);
- else /* double references detected */
- return TRIO_ERROR_RETURN(TRIO_EDBLREF, num);
- }
-
- i = indices[num];
-
- /*
- * FORMAT_PARAMETERS are only present if they must be read,
- * so it makes no sense to check the ignore flag (besides,
- * the flags variable is not set for that particular type)
- */
- if ((parameters[i].type != FORMAT_PARAMETER) &&
- (parameters[i].flags & FLAGS_IGNORE))
- continue; /* for all arguments */
-
- /*
- * The stack arguments are read according to ANSI C89
- * default argument promotions:
- *
- * char = int
- * short = int
- * unsigned char = unsigned int
- * unsigned short = unsigned int
- * float = double
- *
- * In addition to the ANSI C89 these types are read (the
- * default argument promotions of C99 has not been
- * considered yet)
- *
- * long long
- * long double
- * size_t
- * ptrdiff_t
- * intmax_t
- */
- switch (parameters[i].type)
- {
- case FORMAT_GROUP:
- case FORMAT_STRING:
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- parameters[i].data.wstring = (argarray == NULL)
- ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_wchar_t *)
- : (trio_wchar_t *)(argarray[num]);
- }
- else
-#endif
- {
- parameters[i].data.string = (argarray == NULL)
- ? va_arg(TRIO_VA_LIST_DEREF(arglist), char *)
- : (char *)(argarray[num]);
- }
- break;
-
-#if defined(FORMAT_USER_DEFINED)
- case FORMAT_USER_DEFINED:
-#endif
- case FORMAT_POINTER:
- case FORMAT_COUNT:
- case FORMAT_UNKNOWN:
- parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
- : argarray[num];
- break;
-
- case FORMAT_CHAR:
- case FORMAT_INT:
- if (TYPE_SCAN == type)
- {
- if (argarray == NULL)
- parameters[i].data.pointer =
- (trio_pointer_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t);
- else
- {
- if (parameters[i].type == FORMAT_CHAR)
- parameters[i].data.pointer =
- (trio_pointer_t)((char *)argarray[num]);
- else if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.pointer =
- (trio_pointer_t)((short *)argarray[num]);
- else
- parameters[i].data.pointer =
- (trio_pointer_t)((int *)argarray[num]);
- }
- }
- else
- {
-#if defined(QUALIFIER_VARSIZE) || defined(QUALIFIER_FIXED_SIZE)
- if (parameters[i].flags
- & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE))
- {
- if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER)
- {
- /*
- * Variable sizes are mapped onto the fixed sizes, in
- * accordance with integer promotion.
- *
- * Please note that this may not be portable, as we
- * only guess the size, not the layout of the numbers.
- * For example, if int is little-endian, and long is
- * big-endian, then this will fail.
- */
- varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned;
- }
- else
- {
- /* Used for the I modifiers */
- varsize = parameters[i].varsize;
- }
- parameters[i].flags &= ~FLAGS_ALL_VARSIZES;
-
- if (varsize <= (int)sizeof(int))
- ;
- else if (varsize <= (int)sizeof(long))
- parameters[i].flags |= FLAGS_LONG;
-#if defined(QUALIFIER_INTMAX_T)
- else if (varsize <= (int)sizeof(trio_longlong_t))
- parameters[i].flags |= FLAGS_QUAD;
- else
- parameters[i].flags |= FLAGS_INTMAX_T;
-#else
- else
- parameters[i].flags |= FLAGS_QUAD;
-#endif
- }
-#endif /* defined(QUALIFIER_VARSIZE) */
-#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
- if (parameters[i].flags & FLAGS_SIZE_T)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), size_t)
- : (trio_uintmax_t)(*((size_t *)argarray[num]));
- else
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- if (parameters[i].flags & FLAGS_PTRDIFF_T)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), ptrdiff_t)
- : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
- else
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- if (parameters[i].flags & FLAGS_INTMAX_T)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_intmax_t)
- : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
- else
-#endif
- if (parameters[i].flags & FLAGS_QUAD)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_ulonglong_t)
- : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
- else if (parameters[i].flags & FLAGS_LONG)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), long)
- : (trio_uintmax_t)(*((long *)argarray[num]));
- else
- {
- if (argarray == NULL)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int);
- else
- {
- if (parameters[i].type == FORMAT_CHAR)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num]));
- else if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num]));
- else
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num]));
- }
- }
- }
- break;
-
- case FORMAT_PARAMETER:
- /*
- * The parameter for the user-defined specifier is a pointer,
- * whereas the rest (width, precision, base) uses an integer.
- */
- if (parameters[i].flags & FLAGS_USER_DEFINED)
- parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
- : argarray[num];
- else
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int)
- : (trio_uintmax_t)(*((int *)argarray[num]));
- break;
-
- case FORMAT_DOUBLE:
- if (TYPE_SCAN == type)
- {
- if (parameters[i].flags & FLAGS_LONGDOUBLE)
- parameters[i].data.longdoublePointer = (argarray == NULL)
- ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t *)
- : (trio_long_double_t *)argarray[num];
- else
- {
- if (parameters[i].flags & FLAGS_LONG)
- parameters[i].data.doublePointer = (argarray == NULL)
- ? va_arg(TRIO_VA_LIST_DEREF(arglist), double *)
- : (double *)argarray[num];
- else
- parameters[i].data.doublePointer = (argarray == NULL)
- ? (double *)va_arg(TRIO_VA_LIST_DEREF(arglist), float *)
- : (double *)((float *)argarray[num]);
- }
- }
- else
- {
- if (parameters[i].flags & FLAGS_LONGDOUBLE)
- parameters[i].data.longdoubleNumber = (argarray == NULL)
- ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t)
- : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
- else
- {
- if (argarray == NULL)
- parameters[i].data.longdoubleNumber =
- (trio_long_double_t)va_arg(TRIO_VA_LIST_DEREF(arglist), double);
- else
- {
- if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.longdoubleNumber =
- (trio_long_double_t)(*((float *)argarray[num]));
- else
- parameters[i].data.longdoubleNumber =
- (trio_long_double_t)(*((double *)argarray[num]));
- }
- }
- }
- break;
-
-#if defined(FORMAT_ERRNO)
- case FORMAT_ERRNO:
- parameters[i].data.errorNumber = save_errno;
- break;
-#endif
-
- default:
- break;
- }
- } /* for all specifiers */
- return num;
-}
-
-
-/*************************************************************************
- *
- * FORMATTING
- *
- ************************************************************************/
-
-
-/*************************************************************************
- * TrioWriteNumber
- *
- * Description:
- * Output a number.
- * The complexity of this function is a result of the complexity
- * of the dependencies of the flags.
- */
-TRIO_PRIVATE void
-TrioWriteNumber
-TRIO_ARGS6((self, number, flags, width, precision, base),
- trio_class_t *self,
- trio_uintmax_t number,
- trio_flags_t flags,
- int width,
- int precision,
- int base)
-{
- BOOLEAN_T isNegative;
- BOOLEAN_T isNumberZero;
- BOOLEAN_T isPrecisionZero;
- BOOLEAN_T ignoreNumber;
- char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1];
- char *bufferend;
- char *pointer;
- TRIO_CONST char *digits;
- int i;
- int length;
- char *p;
- int count;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
- assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
-
- digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
- if (base == NO_BASE)
- base = BASE_DECIMAL;
-
- isNumberZero = (number == 0);
- isPrecisionZero = (precision == 0);
- ignoreNumber = (isNumberZero
- && isPrecisionZero
- && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL)));
-
- if (flags & FLAGS_UNSIGNED)
- {
- isNegative = FALSE;
- flags &= ~FLAGS_SHOWSIGN;
- }
- else
- {
- isNegative = ((trio_intmax_t)number < 0);
- if (isNegative)
- number = -((trio_intmax_t)number);
- }
-
- if (flags & FLAGS_QUAD)
- number &= (trio_ulonglong_t)-1;
- else if (flags & FLAGS_LONG)
- number &= (unsigned long)-1;
- else
- number &= (unsigned int)-1;
-
- /* Build number */
- pointer = bufferend = &buffer[sizeof(buffer) - 1];
- *pointer-- = NIL;
- for (i = 1; i < (int)sizeof(buffer); i++)
- {
- *pointer-- = digits[number % base];
- number /= base;
- if (number == 0)
- break;
-
- if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1))
- {
- /*
- * We are building the number from the least significant
- * to the most significant digit, so we have to copy the
- * thousand separator backwards
- */
- length = internalThousandSeparatorLength;
- if (((int)(pointer - buffer) - length) > 0)
- {
- p = &internalThousandSeparator[length - 1];
- while (length-- > 0)
- *pointer-- = *p--;
- }
- }
- }
-
- if (! ignoreNumber)
- {
- /* Adjust width */
- width -= (bufferend - pointer) - 1;
- }
-
- /* Adjust precision */
- if (NO_PRECISION != precision)
- {
- precision -= (bufferend - pointer) - 1;
- if (precision < 0)
- precision = 0;
- flags |= FLAGS_NILPADDING;
- }
-
- /* Calculate padding */
- count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION)))
- ? precision
- : 0;
-
- /* Adjust width further */
- if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
- width--;
- if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
- {
- switch (base)
- {
- case BASE_BINARY:
- case BASE_HEX:
- width -= 2;
- break;
- case BASE_OCTAL:
- if (!(flags & FLAGS_NILPADDING) || (count == 0))
- width--;
- break;
- default:
- break;
- }
- }
-
- /* Output prefixes spaces if needed */
- if (! ((flags & FLAGS_LEFTADJUST) ||
- ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION))))
- {
- while (width-- > count)
- self->OutStream(self, CHAR_ADJUST);
- }
-
- /* width has been adjusted for signs and alternatives */
- if (isNegative)
- self->OutStream(self, '-');
- else if (flags & FLAGS_SHOWSIGN)
- self->OutStream(self, '+');
- else if (flags & FLAGS_SPACE)
- self->OutStream(self, ' ');
-
- /* Prefix is not written when the value is zero */
- if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
- {
- switch (base)
- {
- case BASE_BINARY:
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b');
- break;
-
- case BASE_OCTAL:
- if (!(flags & FLAGS_NILPADDING) || (count == 0))
- self->OutStream(self, '0');
- break;
-
- case BASE_HEX:
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
- break;
-
- default:
- break;
- } /* switch base */
- }
-
- /* Output prefixed zero padding if needed */
- if (flags & FLAGS_NILPADDING)
- {
- if (precision == NO_PRECISION)
- precision = width;
- while (precision-- > 0)
- {
- self->OutStream(self, '0');
- width--;
- }
- }
-
- if (! ignoreNumber)
- {
- /* Output the number itself */
- while (*(++pointer))
- {
- self->OutStream(self, *pointer);
- }
- }
-
- /* Output trailing spaces if needed */
- if (flags & FLAGS_LEFTADJUST)
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-}
-
-/*************************************************************************
- * TrioWriteStringCharacter
- *
- * Description:
- * Output a single character of a string
- */
-TRIO_PRIVATE void
-TrioWriteStringCharacter
-TRIO_ARGS3((self, ch, flags),
- trio_class_t *self,
- int ch,
- trio_flags_t flags)
-{
- if (flags & FLAGS_ALTERNATIVE)
- {
- if (! isprint(ch))
- {
- /*
- * Non-printable characters are converted to C escapes or
- * \number, if no C escape exists.
- */
- self->OutStream(self, CHAR_BACKSLASH);
- switch (ch)
- {
- case '\007': self->OutStream(self, 'a'); break;
- case '\b': self->OutStream(self, 'b'); break;
- case '\f': self->OutStream(self, 'f'); break;
- case '\n': self->OutStream(self, 'n'); break;
- case '\r': self->OutStream(self, 'r'); break;
- case '\t': self->OutStream(self, 't'); break;
- case '\v': self->OutStream(self, 'v'); break;
- case '\\': self->OutStream(self, '\\'); break;
- default:
- self->OutStream(self, 'x');
- TrioWriteNumber(self, (trio_uintmax_t)ch,
- FLAGS_UNSIGNED | FLAGS_NILPADDING,
- 2, 2, BASE_HEX);
- break;
- }
- }
- else if (ch == CHAR_BACKSLASH)
- {
- self->OutStream(self, CHAR_BACKSLASH);
- self->OutStream(self, CHAR_BACKSLASH);
- }
- else
- {
- self->OutStream(self, ch);
- }
- }
- else
- {
- self->OutStream(self, ch);
- }
-}
-
-/*************************************************************************
- * TrioWriteString
- *
- * Description:
- * Output a string
- */
-TRIO_PRIVATE void
-TrioWriteString
-TRIO_ARGS5((self, string, flags, width, precision),
- trio_class_t *self,
- TRIO_CONST char *string,
- trio_flags_t flags,
- int width,
- int precision)
-{
- int length;
- int ch;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
-
- if (string == NULL)
- {
- string = internalNullString;
- length = sizeof(internalNullString) - 1;
- /* Disable quoting for the null pointer */
- flags &= (~FLAGS_QUOTE);
- width = 0;
- }
- else
- {
- length = trio_length(string);
- }
- if ((NO_PRECISION != precision) &&
- (precision < length))
- {
- length = precision;
- }
- width -= length;
-
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-
- if (! (flags & FLAGS_LEFTADJUST))
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-
- while (length-- > 0)
- {
- /* The ctype parameters must be an unsigned char (or EOF) */
- ch = (int)((unsigned char)(*string++));
- TrioWriteStringCharacter(self, ch, flags);
- }
-
- if (flags & FLAGS_LEFTADJUST)
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-}
-
-/*************************************************************************
- * TrioWriteWideStringCharacter
- *
- * Description:
- * Output a wide string as a multi-byte sequence
- */
-#if TRIO_WIDECHAR
-TRIO_PRIVATE int
-TrioWriteWideStringCharacter
-TRIO_ARGS4((self, wch, flags, width),
- trio_class_t *self,
- trio_wchar_t wch,
- trio_flags_t flags,
- int width)
-{
- int size;
- int i;
- int ch;
- char *string;
- char buffer[MB_LEN_MAX + 1];
-
- if (width == NO_WIDTH)
- width = sizeof(buffer);
-
- size = wctomb(buffer, wch);
- if ((size <= 0) || (size > width) || (buffer[0] == NIL))
- return 0;
-
- string = buffer;
- i = size;
- while ((width >= i) && (width-- > 0) && (i-- > 0))
- {
- /* The ctype parameters must be an unsigned char (or EOF) */
- ch = (int)((unsigned char)(*string++));
- TrioWriteStringCharacter(self, ch, flags);
- }
- return size;
-}
-#endif /* TRIO_WIDECHAR */
-
-/*************************************************************************
- * TrioWriteWideString
- *
- * Description:
- * Output a wide character string as a multi-byte string
- */
-#if TRIO_WIDECHAR
-TRIO_PRIVATE void
-TrioWriteWideString
-TRIO_ARGS5((self, wstring, flags, width, precision),
- trio_class_t *self,
- TRIO_CONST trio_wchar_t *wstring,
- trio_flags_t flags,
- int width,
- int precision)
-{
- int length;
- int size;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- if (wstring == NULL)
- {
- TrioWriteString(self, NULL, flags, width, precision);
- return;
- }
-
- if (NO_PRECISION == precision)
- {
- length = INT_MAX;
- }
- else
- {
- length = precision;
- width -= length;
- }
-
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-
- if (! (flags & FLAGS_LEFTADJUST))
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-
- while (length > 0)
- {
- size = TrioWriteWideStringCharacter(self, *wstring++, flags, length);
- if (size == 0)
- break; /* while */
- length -= size;
- }
-
- if (flags & FLAGS_LEFTADJUST)
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-}
-#endif /* TRIO_WIDECHAR */
-
-/*************************************************************************
- * TrioWriteDouble
- *
- * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm
- *
- * "5.2.4.2.2 paragraph #4
- *
- * The accuracy [...] is implementation defined, as is the accuracy
- * of the conversion between floating-point internal representations
- * and string representations performed by the library routine in
- * "
- */
-/* FIXME: handle all instances of constant long-double number (L)
- * and *l() math functions.
- */
-TRIO_PRIVATE void
-TrioWriteDouble
-TRIO_ARGS6((self, number, flags, width, precision, base),
- trio_class_t *self,
- trio_long_double_t number,
- trio_flags_t flags,
- int width,
- int precision,
- int base)
-{
- trio_long_double_t integerNumber;
- trio_long_double_t fractionNumber;
- trio_long_double_t workNumber;
- int integerDigits;
- int fractionDigits;
- int exponentDigits;
- int baseDigits;
- int integerThreshold;
- int fractionThreshold;
- int expectedWidth;
- int exponent = 0;
- unsigned int uExponent = 0;
- int exponentBase;
- trio_long_double_t dblBase;
- trio_long_double_t dblIntegerBase;
- trio_long_double_t dblFractionBase;
- trio_long_double_t integerAdjust;
- trio_long_double_t fractionAdjust;
- BOOLEAN_T isNegative;
- BOOLEAN_T isExponentNegative = FALSE;
- BOOLEAN_T requireTwoDigitExponent;
- BOOLEAN_T isHex;
- TRIO_CONST char *digits;
- char *groupingPointer;
- int i;
- int index;
- BOOLEAN_T hasOnlyZeroes;
- int zeroes = 0;
- register int trailingZeroes;
- BOOLEAN_T keepTrailingZeroes;
- BOOLEAN_T keepDecimalPoint;
- trio_long_double_t epsilon;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
- assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
-
- /* Determine sign and look for special quantities */
- switch (trio_fpclassify_and_signbit(number, &isNegative))
- {
- case TRIO_FP_NAN:
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? NAN_UPPER
- : NAN_LOWER,
- flags, width, precision);
- return;
-
- case TRIO_FP_INFINITE:
- if (isNegative)
- {
- /* Negative infinity */
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? "-" INFINITE_UPPER
- : "-" INFINITE_LOWER,
- flags, width, precision);
- return;
- }
- else
- {
- /* Positive infinity */
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? INFINITE_UPPER
- : INFINITE_LOWER,
- flags, width, precision);
- return;
- }
-
- default:
- /* Finitude */
- break;
- }
-
- /* Normal numbers */
- if (flags & FLAGS_LONGDOUBLE)
- {
- baseDigits = (base == 10)
- ? LDBL_DIG
- : (int)floor(LDBL_MANT_DIG / TrioLogarithmBase(base));
- epsilon = LDBL_EPSILON;
- }
- else if (flags & FLAGS_SHORT)
- {
- baseDigits = (base == BASE_DECIMAL)
- ? FLT_DIG
- : (int)floor(FLT_MANT_DIG / TrioLogarithmBase(base));
- epsilon = FLT_EPSILON;
- }
- else
- {
- baseDigits = (base == BASE_DECIMAL)
- ? DBL_DIG
- : (int)floor(DBL_MANT_DIG / TrioLogarithmBase(base));
- epsilon = DBL_EPSILON;
- }
-
- digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
- isHex = (base == BASE_HEX);
- if (base == NO_BASE)
- base = BASE_DECIMAL;
- dblBase = (trio_long_double_t)base;
- keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) ||
- ( (flags & FLAGS_FLOAT_G) &&
- !(flags & FLAGS_ALTERNATIVE) ) );
-
- if (flags & FLAGS_ROUNDING)
- precision = baseDigits;
-
- if (precision == NO_PRECISION)
- {
- if (isHex)
- {
- keepTrailingZeroes = FALSE;
- precision = FLT_MANT_DIG;
- }
- else
- {
- precision = FLT_DIG;
- }
- }
-
- if (isNegative)
- number = -number;
-
- if (isHex)
- flags |= FLAGS_FLOAT_E;
-
- if (flags & FLAGS_FLOAT_G)
- {
- if (precision == 0)
- precision = 1;
-
- if ((number < 1.0E-4) || (number > powl(base,
- (trio_long_double_t)precision)))
- {
- /* Use scientific notation */
- flags |= FLAGS_FLOAT_E;
- }
- else if (number < 1.0)
- {
- /*
- * Use normal notation. If the integer part of the number is
- * zero, then adjust the precision to include leading fractional
- * zeros.
- */
- workNumber = TrioLogarithm(number, base);
- workNumber = TRIO_FABS(workNumber);
- if (workNumber - floorl(workNumber) < 0.001)
- workNumber--;
- zeroes = (int)floorl(workNumber);
- }
- }
-
- if (flags & FLAGS_FLOAT_E)
- {
- /* Scale the number */
- workNumber = TrioLogarithm(number, base);
- if (trio_isinf(workNumber) == -1)
- {
- exponent = 0;
- /* Undo setting */
- if (flags & FLAGS_FLOAT_G)
- flags &= ~FLAGS_FLOAT_E;
- }
- else
- {
- exponent = (int)floorl(workNumber);
- number /= powl(dblBase, (trio_long_double_t)exponent);
- isExponentNegative = (exponent < 0);
- uExponent = (isExponentNegative) ? -exponent : exponent;
- if (isHex)
- uExponent *= 4; /* log16(2) */
- /* No thousand separators */
- flags &= ~FLAGS_QUOTE;
- }
- }
-
- integerNumber = floorl(number);
- fractionNumber = number - integerNumber;
-
- /*
- * Truncated number.
- *
- * Precision is number of significant digits for FLOAT_G
- * and number of fractional digits for others.
- */
- integerDigits = (integerNumber > epsilon)
- ? 1 + (int)TrioLogarithm(integerNumber, base)
- : 1;
- fractionDigits = ((flags & FLAGS_FLOAT_G) && (zeroes == 0))
- ? precision - integerDigits
- : zeroes + precision;
-
- dblFractionBase = TrioPower(base, fractionDigits);
-
- workNumber = number + 0.5 / dblFractionBase;
- if (floorl(number) != floorl(workNumber))
- {
- if (flags & FLAGS_FLOAT_E)
- {
- /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */
- exponent++;
- isExponentNegative = (exponent < 0);
- uExponent = (isExponentNegative) ? -exponent : exponent;
- if (isHex)
- uExponent *= 4; /* log16(2) */
- workNumber = (number + 0.5 / dblFractionBase) / dblBase;
- integerNumber = floorl(workNumber);
- fractionNumber = workNumber - integerNumber;
- }
- else
- {
- /* Adjust if number was rounded up one digit (ie. 99 to 100) */
- integerNumber = floorl(number + 0.5);
- fractionNumber = 0.0;
- integerDigits = (integerNumber > epsilon)
- ? 1 + (int)TrioLogarithm(integerNumber, base)
- : 1;
- }
- }
-
- /* Estimate accuracy */
- integerAdjust = fractionAdjust = 0.5;
- if (flags & FLAGS_ROUNDING)
- {
- if (integerDigits > baseDigits)
- {
- integerThreshold = baseDigits;
- fractionDigits = 0;
- dblFractionBase = 1.0;
- fractionThreshold = 0;
- precision = 0; /* Disable decimal-point */
- integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1);
- fractionAdjust = 0.0;
- }
- else
- {
- integerThreshold = integerDigits;
- fractionThreshold = fractionDigits - integerThreshold;
- fractionAdjust = 1.0;
- }
- }
- else
- {
- integerThreshold = INT_MAX;
- fractionThreshold = INT_MAX;
- }
-
- /*
- * Calculate expected width.
- * sign + integer part + thousands separators + decimal point
- * + fraction + exponent
- */
- fractionAdjust /= dblFractionBase;
- hasOnlyZeroes = (floorl((fractionNumber + fractionAdjust) * dblFractionBase) < epsilon);
- keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) ||
- !((precision == 0) ||
- (!keepTrailingZeroes && hasOnlyZeroes)) );
- if (flags & FLAGS_FLOAT_E)
- {
- exponentDigits = (uExponent == 0)
- ? 1
- : (int)ceil(TrioLogarithm((double)(uExponent + 1),
- (isHex) ? 10.0 : base));
- }
- else
- exponentDigits = 0;
- requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1));
-
- expectedWidth = integerDigits + fractionDigits
- + (keepDecimalPoint
- ? internalDecimalPointLength
- : 0)
- + ((flags & FLAGS_QUOTE)
- ? TrioCalcThousandSeparatorLength(integerDigits)
- : 0);
- if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
- expectedWidth += sizeof("-") - 1;
- if (exponentDigits > 0)
- expectedWidth += exponentDigits +
- ((requireTwoDigitExponent ? sizeof("E+0") : sizeof("E+")) - 1);
- if (isHex)
- expectedWidth += sizeof("0X") - 1;
-
- /* Output prefixing */
- if (flags & FLAGS_NILPADDING)
- {
- /* Leading zeros must be after sign */
- if (isNegative)
- self->OutStream(self, '-');
- else if (flags & FLAGS_SHOWSIGN)
- self->OutStream(self, '+');
- else if (flags & FLAGS_SPACE)
- self->OutStream(self, ' ');
- if (isHex)
- {
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
- }
- if (!(flags & FLAGS_LEFTADJUST))
- {
- for (i = expectedWidth; i < width; i++)
- {
- self->OutStream(self, '0');
- }
- }
- }
- else
- {
- /* Leading spaces must be before sign */
- if (!(flags & FLAGS_LEFTADJUST))
- {
- for (i = expectedWidth; i < width; i++)
- {
- self->OutStream(self, CHAR_ADJUST);
- }
- }
- if (isNegative)
- self->OutStream(self, '-');
- else if (flags & FLAGS_SHOWSIGN)
- self->OutStream(self, '+');
- else if (flags & FLAGS_SPACE)
- self->OutStream(self, ' ');
- if (isHex)
- {
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
- }
- }
-
- /* Output the integer part and thousand separators */
- dblIntegerBase = 1.0 / TrioPower(base, integerDigits - 1);
- for (i = 0; i < integerDigits; i++)
- {
- workNumber = floorl(((integerNumber + integerAdjust) * dblIntegerBase));
- if (i > integerThreshold)
- {
- /* Beyond accuracy */
- self->OutStream(self, digits[0]);
- }
- else
- {
- self->OutStream(self, digits[(int)fmodl(workNumber, dblBase)]);
- }
- dblIntegerBase *= dblBase;
-
- if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)
- && TrioFollowedBySeparator(integerDigits - i))
- {
- for (groupingPointer = internalThousandSeparator;
- *groupingPointer != NIL;
- groupingPointer++)
- {
- self->OutStream(self, *groupingPointer);
- }
- }
- }
-
- /* Insert decimal point and build the fraction part */
- trailingZeroes = 0;
-
- if (keepDecimalPoint)
- {
- if (internalDecimalPoint)
- {
- self->OutStream(self, internalDecimalPoint);
- }
- else
- {
- for (i = 0; i < internalDecimalPointLength; i++)
- {
- self->OutStream(self, internalDecimalPointString[i]);
- }
- }
- }
-
- for (i = 0; i < fractionDigits; i++)
- {
- if ((integerDigits > integerThreshold) || (i > fractionThreshold))
- {
- /* Beyond accuracy */
- trailingZeroes++;
- }
- else
- {
- fractionNumber *= dblBase;
- fractionAdjust *= dblBase;
- workNumber = floorl(fractionNumber + fractionAdjust);
- fractionNumber -= workNumber;
- index = (int)fmodl(workNumber, dblBase);
- if (index == 0)
- {
- trailingZeroes++;
- }
- else
- {
- while (trailingZeroes > 0)
- {
- /* Not trailing zeroes after all */
- self->OutStream(self, digits[0]);
- trailingZeroes--;
- }
- self->OutStream(self, digits[index]);
- }
- }
- }
-
- if (keepTrailingZeroes)
- {
- while (trailingZeroes > 0)
- {
- self->OutStream(self, digits[0]);
- trailingZeroes--;
- }
- }
-
- /* Output exponent */
- if (exponentDigits > 0)
- {
- self->OutStream(self,
- isHex
- ? ((flags & FLAGS_UPPER) ? 'P' : 'p')
- : ((flags & FLAGS_UPPER) ? 'E' : 'e'));
- self->OutStream(self, (isExponentNegative) ? '-' : '+');
-
- /* The exponent must contain at least two digits */
- if (requireTwoDigitExponent)
- self->OutStream(self, '0');
-
- if (isHex)
- base = 10.0;
- exponentBase = (int)TrioPower(base, exponentDigits - 1);
- for (i = 0; i < exponentDigits; i++)
- {
- self->OutStream(self, digits[(uExponent / exponentBase) % base]);
- exponentBase /= base;
- }
- }
- /* Output trailing spaces */
- if (flags & FLAGS_LEFTADJUST)
- {
- for (i = expectedWidth; i < width; i++)
- {
- self->OutStream(self, CHAR_ADJUST);
- }
- }
-}
-
-/*************************************************************************
- * TrioFormatProcess
- *
- * Description:
- * This is the main engine for formatting output
- */
-TRIO_PRIVATE int
-TrioFormatProcess
-TRIO_ARGS3((data, format, parameters),
- trio_class_t *data,
- TRIO_CONST char *format,
- trio_parameter_t *parameters)
-{
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- int charlen;
-#endif
- int i;
- TRIO_CONST char *string;
- trio_pointer_t pointer;
- trio_flags_t flags;
- int width;
- int precision;
- int base;
- int index;
-
- index = 0;
- i = 0;
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- while (format[index])
- {
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- if (! isascii(format[index]))
- {
- charlen = mblen(&format[index], MB_LEN_MAX);
- /*
- * Only valid multibyte characters are handled here. Invalid
- * multibyte characters (charlen == -1) are handled as normal
- * characters.
- */
- if (charlen != -1)
- {
- while (charlen-- > 0)
- {
- data->OutStream(data, format[index++]);
- }
- continue; /* while characters left in formatting string */
- }
- }
-#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
- if (CHAR_IDENTIFIER == format[index])
- {
- if (CHAR_IDENTIFIER == format[index + 1])
- {
- data->OutStream(data, CHAR_IDENTIFIER);
- index += 2;
- }
- else
- {
- /* Skip the parameter entries */
- while (parameters[i].type == FORMAT_PARAMETER)
- i++;
-
- flags = parameters[i].flags;
-
- /* Find width */
- width = parameters[i].width;
- if (flags & FLAGS_WIDTH_PARAMETER)
- {
- /* Get width from parameter list */
- width = (int)parameters[width].data.number.as_signed;
- if (width < 0)
- {
- /*
- * A negative width is the same as the - flag and
- * a positive width.
- */
- flags |= FLAGS_LEFTADJUST;
- flags &= ~FLAGS_NILPADDING;
- width = -width;
- }
- }
-
- /* Find precision */
- if (flags & FLAGS_PRECISION)
- {
- precision = parameters[i].precision;
- if (flags & FLAGS_PRECISION_PARAMETER)
- {
- /* Get precision from parameter list */
- precision = (int)parameters[precision].data.number.as_signed;
- if (precision < 0)
- {
- /*
- * A negative precision is the same as no
- * precision
- */
- precision = NO_PRECISION;
- }
- }
- }
- else
- {
- precision = NO_PRECISION;
- }
-
- /* Find base */
- base = parameters[i].base;
- if (flags & FLAGS_BASE_PARAMETER)
- {
- /* Get base from parameter list */
- base = (int)parameters[base].data.number.as_signed;
- }
-
- switch (parameters[i].type)
- {
- case FORMAT_CHAR:
- if (flags & FLAGS_QUOTE)
- data->OutStream(data, CHAR_QUOTE);
- if (! (flags & FLAGS_LEFTADJUST))
- {
- while (--width > 0)
- data->OutStream(data, CHAR_ADJUST);
- }
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- TrioWriteWideStringCharacter(data,
- (trio_wchar_t)parameters[i].data.number.as_signed,
- flags,
- NO_WIDTH);
- }
- else
-#endif
- {
- TrioWriteStringCharacter(data,
- (int)parameters[i].data.number.as_signed,
- flags);
- }
-
- if (flags & FLAGS_LEFTADJUST)
- {
- while(--width > 0)
- data->OutStream(data, CHAR_ADJUST);
- }
- if (flags & FLAGS_QUOTE)
- data->OutStream(data, CHAR_QUOTE);
-
- break; /* FORMAT_CHAR */
-
- case FORMAT_INT:
- TrioWriteNumber(data,
- parameters[i].data.number.as_unsigned,
- flags,
- width,
- precision,
- base);
-
- break; /* FORMAT_INT */
-
- case FORMAT_DOUBLE:
- TrioWriteDouble(data,
- parameters[i].data.longdoubleNumber,
- flags,
- width,
- precision,
- base);
- break; /* FORMAT_DOUBLE */
-
- case FORMAT_STRING:
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- TrioWriteWideString(data,
- parameters[i].data.wstring,
- flags,
- width,
- precision);
- }
- else
-#endif
- {
- TrioWriteString(data,
- parameters[i].data.string,
- flags,
- width,
- precision);
- }
- break; /* FORMAT_STRING */
-
- case FORMAT_POINTER:
- {
- trio_reference_t reference;
-
- reference.data = data;
- reference.parameter = ¶meters[i];
- trio_print_pointer(&reference, parameters[i].data.pointer);
- }
- break; /* FORMAT_POINTER */
-
- case FORMAT_COUNT:
- pointer = parameters[i].data.pointer;
- if (NULL != pointer)
- {
- /*
- * C99 paragraph 7.19.6.1.8 says "the number of
- * characters written to the output stream so far by
- * this call", which is data->committed
- */
-#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
- if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)data->committed;
- else
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)data->committed;
- else
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)data->committed;
- else
-#endif
- if (flags & FLAGS_QUAD)
- {
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed;
- }
- else if (flags & FLAGS_LONG)
- {
- *(long int *)pointer = (long int)data->committed;
- }
- else if (flags & FLAGS_SHORT)
- {
- *(short int *)pointer = (short int)data->committed;
- }
- else
- {
- *(int *)pointer = (int)data->committed;
- }
- }
- break; /* FORMAT_COUNT */
-
- case FORMAT_PARAMETER:
- break; /* FORMAT_PARAMETER */
-
-#if defined(FORMAT_ERRNO)
- case FORMAT_ERRNO:
- string = trio_error(parameters[i].data.errorNumber);
- if (string)
- {
- TrioWriteString(data,
- string,
- flags,
- width,
- precision);
- }
- else
- {
- data->OutStream(data, '#');
- TrioWriteNumber(data,
- (trio_uintmax_t)parameters[i].data.errorNumber,
- flags,
- width,
- precision,
- BASE_DECIMAL);
- }
- break; /* FORMAT_ERRNO */
-#endif /* defined(FORMAT_ERRNO) */
-
-#if defined(FORMAT_USER_DEFINED)
- case FORMAT_USER_DEFINED:
- {
- trio_reference_t reference;
- trio_userdef_t *def = NULL;
-
- if (parameters[i].user_name[0] == NIL)
- {
- /* Use handle */
- if ((i > 0) ||
- (parameters[i - 1].type == FORMAT_PARAMETER))
- def = (trio_userdef_t *)parameters[i - 1].data.pointer;
- }
- else
- {
- /* Look up namespace */
- def = TrioFindNamespace(parameters[i].user_name, NULL);
- }
- if (def) {
- reference.data = data;
- reference.parameter = ¶meters[i];
- def->callback(&reference);
- }
- }
- break;
-#endif /* defined(FORMAT_USER_DEFINED) */
-
- default:
- break;
- } /* switch parameter type */
-
- /* Prepare for next */
- index = parameters[i].indexAfterSpecifier;
- i++;
- }
- }
- else /* not identifier */
- {
- data->OutStream(data, format[index++]);
- }
- }
- return data->processed;
-}
-
-/*************************************************************************
- * TrioFormatRef
- */
-TRIO_PRIVATE int
-TrioFormatRef
-TRIO_ARGS4((reference, format, arglist, argarray),
- trio_reference_t *reference,
- TRIO_CONST char *format,
- TRIO_VA_LIST_PTR arglist,
- trio_pointer_t *argarray)
-{
- int status;
- trio_parameter_t parameters[MAX_PARAMETERS];
-
- status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
- if (status < 0)
- return status;
-
- status = TrioFormatProcess(reference->data, format, parameters);
- if (reference->data->error != 0)
- {
- status = reference->data->error;
- }
- return status;
-}
-
-/*************************************************************************
- * TrioFormat
- */
-TRIO_PRIVATE int
-TrioFormat
-TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray),
- trio_pointer_t destination,
- size_t destinationSize,
- void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
- TRIO_CONST char *format,
- TRIO_VA_LIST_PTR arglist,
- trio_pointer_t *argarray)
-{
- int status;
- trio_class_t data;
- trio_parameter_t parameters[MAX_PARAMETERS];
-
- assert(VALID(OutStream));
- assert(VALID(format));
-
- memset(&data, 0, sizeof(data));
- data.OutStream = OutStream;
- data.location = destination;
- data.max = destinationSize;
- data.error = 0;
-
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
-
- status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
- if (status < 0)
- return status;
-
- status = TrioFormatProcess(&data, format, parameters);
- if (data.error != 0)
- {
- status = data.error;
- }
- return status;
-}
-
-/*************************************************************************
- * TrioOutStreamFile
- */
-TRIO_PRIVATE void
-TrioOutStreamFile
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- FILE *file;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- file = (FILE *)self->location;
- self->processed++;
- if (fputc(output, file) == EOF)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0);
- }
- else
- {
- self->committed++;
- }
-}
-
-/*************************************************************************
- * TrioOutStreamFileDescriptor
- */
-TRIO_PRIVATE void
-TrioOutStreamFileDescriptor
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- int fd;
- char ch;
-
- assert(VALID(self));
-
- fd = *((int *)self->location);
- ch = (char)output;
- self->processed++;
- if (write(fd, &ch, sizeof(char)) == -1)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
- }
- else
- {
- self->committed++;
- }
-}
-
-/*************************************************************************
- * TrioOutStreamCustom
- */
-TRIO_PRIVATE void
-TrioOutStreamCustom
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- int status;
- trio_custom_t *data;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- data = (trio_custom_t *)self->location;
- if (data->stream.out)
- {
- status = (data->stream.out)(data->closure, output);
- if (status >= 0)
- {
- self->committed++;
- }
- else
- {
- if (self->error == 0)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status);
- }
- }
- }
- self->processed++;
-}
-
-/*************************************************************************
- * TrioOutStreamString
- */
-TRIO_PRIVATE void
-TrioOutStreamString
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- char **buffer;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- buffer = (char **)self->location;
- **buffer = (char)output;
- (*buffer)++;
- self->processed++;
- self->committed++;
-}
-
-/*************************************************************************
- * TrioOutStreamStringMax
- */
-TRIO_PRIVATE void
-TrioOutStreamStringMax
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- char **buffer;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- buffer = (char **)self->location;
-
- if (self->processed < self->max)
- {
- **buffer = (char)output;
- (*buffer)++;
- self->committed++;
- }
- self->processed++;
-}
-
-/*************************************************************************
- * TrioOutStreamStringDynamic
- */
-TRIO_PRIVATE void
-TrioOutStreamStringDynamic
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- assert(VALID(self));
- assert(VALID(self->location));
-
- if (self->error == 0)
- {
- trio_xstring_append_char((trio_string_t *)self->location,
- (char)output);
- self->committed++;
- }
- /* The processed variable must always be increased */
- self->processed++;
-}
-
-/*************************************************************************
- *
- * Formatted printing functions
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_printf.h"
-#endif
-/** @addtogroup Printf
- @{
-*/
-
-/*************************************************************************
- * printf
- */
-
-/**
- Print to standard output stream.
-
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_printf
-TRIO_VARGS2((format, va_alist),
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print to standard output stream.
-
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vprintf
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
-}
-
-/**
- Print to standard output stream.
-
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_printfv
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- trio_pointer_t * args)
-{
- assert(VALID(format));
-
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, NULL, args);
-}
-
-/*************************************************************************
- * fprintf
- */
-
-/**
- Print to file.
-
- @param file File pointer.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_fprintf
-TRIO_VARGS3((file, format, va_alist),
- FILE *file,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(file));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print to file.
-
- @param file File pointer.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vfprintf
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
-}
-
-/**
- Print to file.
-
- @param file File pointer.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_fprintfv
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- trio_pointer_t * args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioFormat(file, 0, TrioOutStreamFile, format, NULL, args);
-}
-
-/*************************************************************************
- * dprintf
- */
-
-/**
- Print to file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_dprintf
-TRIO_VARGS3((fd, format, va_alist),
- int fd,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print to file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vdprintf
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
-}
-
-/**
- Print to file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_dprintfv
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(format));
-
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, NULL, args);
-}
-
-/*************************************************************************
- * cprintf
- */
-TRIO_PUBLIC int
-trio_cprintf
-TRIO_VARGS4((stream, closure, format, va_alist),
- trio_outstream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- data.stream.out = stream;
- data.closure = closure;
- status = TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vcprintf
-TRIO_ARGS4((stream, closure, format, args),
- trio_outstream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- va_list args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.out = stream;
- data.closure = closure;
- return TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
-}
-
-TRIO_PUBLIC int
-trio_cprintfv
-TRIO_ARGS4((stream, closure, format, args),
- trio_outstream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- void **args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.out = stream;
- data.closure = closure;
- return TrioFormat(&data, 0, TrioOutStreamCustom, format, NULL, args);
-}
-
-/*************************************************************************
- * sprintf
- */
-
-/**
- Print to string.
-
- @param buffer Output string.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_sprintf
-TRIO_VARGS3((buffer, format, va_alist),
- char *buffer,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
- *buffer = NIL; /* Terminate with NIL character */
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print to string.
-
- @param buffer Output string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vsprintf
-TRIO_ARGS3((buffer, format, args),
- char *buffer,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
- *buffer = NIL;
- return status;
-}
-
-/**
- Print to string.
-
- @param buffer Output string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_sprintfv
-TRIO_ARGS3((buffer, format, args),
- char *buffer,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, NULL, args);
- *buffer = NIL;
- return status;
-}
-
-/*************************************************************************
- * snprintf
- */
-
-/**
- Print at most @p max characters to string.
-
- @param buffer Output string.
- @param max Maximum number of characters to print.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_snprintf
-TRIO_VARGS4((buffer, max, format, va_alist),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
- if (max > 0)
- *buffer = NIL;
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print at most @p max characters to string.
-
- @param buffer Output string.
- @param max Maximum number of characters to print.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vsnprintf
-TRIO_ARGS4((buffer, max, format, args),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
- if (max > 0)
- *buffer = NIL;
- return status;
-}
-
-/**
- Print at most @p max characters to string.
-
- @param buffer Output string.
- @param max Maximum number of characters to print.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_snprintfv
-TRIO_ARGS4((buffer, max, format, args),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, NULL, args);
- if (max > 0)
- *buffer = NIL;
- return status;
-}
-
-/*************************************************************************
- * snprintfcat
- * Appends the new string to the buffer string overwriting the '\0'
- * character at the end of buffer.
- */
-TRIO_PUBLIC int
-trio_snprintfcat
-TRIO_VARGS4((buffer, max, format, va_alist),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
- size_t buf_len;
-
- TRIO_VA_START(args, format);
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- buf_len = trio_length(buffer);
- buffer = &buffer[buf_len];
-
- status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- *buffer = NIL;
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vsnprintfcat
-TRIO_ARGS4((buffer, max, format, args),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
- size_t buf_len;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- buf_len = trio_length(buffer);
- buffer = &buffer[buf_len];
- status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
- *buffer = NIL;
- return status;
-}
-
-/*************************************************************************
- * trio_aprintf
- */
-
-/* Deprecated */
-TRIO_PUBLIC char *
-trio_aprintf
-TRIO_VARGS2((format, va_alist),
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- va_list args;
- trio_string_t *info;
- char *result = NULL;
-
- assert(VALID(format));
-
- info = trio_xstring_duplicate("");
- if (info)
- {
- TRIO_VA_START(args, format);
- (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
-
- trio_string_terminate(info);
- result = trio_string_extract(info);
- trio_string_destroy(info);
- }
- return result;
-}
-
-/* Deprecated */
-TRIO_PUBLIC char *
-trio_vaprintf
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- va_list args)
-{
- trio_string_t *info;
- char *result = NULL;
-
- assert(VALID(format));
-
- info = trio_xstring_duplicate("");
- if (info)
- {
- (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, TRIO_VA_LIST_ADDR(args), NULL);
- trio_string_terminate(info);
- result = trio_string_extract(info);
- trio_string_destroy(info);
- }
- return result;
-}
-
-TRIO_PUBLIC int
-trio_asprintf
-TRIO_VARGS3((result, format, va_alist),
- char **result,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- va_list args;
- int status;
- trio_string_t *info;
-
- assert(VALID(format));
-
- *result = NULL;
-
- info = trio_xstring_duplicate("");
- if (info == NULL)
- {
- status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
- }
- else
- {
- TRIO_VA_START(args, format);
- status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- if (status >= 0)
- {
- trio_string_terminate(info);
- *result = trio_string_extract(info);
- }
- trio_string_destroy(info);
- }
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vasprintf
-TRIO_ARGS3((result, format, args),
- char **result,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
- trio_string_t *info;
-
- assert(VALID(format));
-
- *result = NULL;
-
- info = trio_xstring_duplicate("");
- if (info == NULL)
- {
- status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
- }
- else
- {
- status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, TRIO_VA_LIST_ADDR(args), NULL);
- if (status >= 0)
- {
- trio_string_terminate(info);
- *result = trio_string_extract(info);
- }
- trio_string_destroy(info);
- }
- return status;
-}
-
-/** @} End of Printf documentation module */
-
-/*************************************************************************
- *
- * CALLBACK
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_register.h"
-#endif
-/**
- @addtogroup UserDefined
- @{
-*/
-
-#if TRIO_EXTENSION
-
-/*************************************************************************
- * trio_register
- */
-
-/**
- Register new user-defined specifier.
-
- @param callback
- @param name
- @return Handle.
- */
-TRIO_PUBLIC trio_pointer_t
-trio_register
-TRIO_ARGS2((callback, name),
- trio_callback_t callback,
- TRIO_CONST char *name)
-{
- trio_userdef_t *def;
- trio_userdef_t *prev = NULL;
-
- if (callback == NULL)
- return NULL;
-
- if (name)
- {
- /* Handle built-in namespaces */
- if (name[0] == ':')
- {
- if (trio_equal(name, ":enter"))
- {
- internalEnterCriticalRegion = callback;
- }
- else if (trio_equal(name, ":leave"))
- {
- internalLeaveCriticalRegion = callback;
- }
- return NULL;
- }
-
- /* Bail out if namespace is too long */
- if (trio_length(name) >= MAX_USER_NAME)
- return NULL;
-
- /* Bail out if namespace already is registered */
- def = TrioFindNamespace(name, &prev);
- if (def)
- return NULL;
- }
-
- def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t));
- if (def)
- {
- if (internalEnterCriticalRegion)
- (void)internalEnterCriticalRegion(NULL);
-
- if (name)
- {
- /* Link into internal list */
- if (prev == NULL)
- internalUserDef = def;
- else
- prev->next = def;
- }
- /* Initialize */
- def->callback = callback;
- def->name = (name == NULL)
- ? NULL
- : trio_duplicate(name);
- def->next = NULL;
-
- if (internalLeaveCriticalRegion)
- (void)internalLeaveCriticalRegion(NULL);
- }
- return (trio_pointer_t)def;
-}
-
-/**
- Unregister an existing user-defined specifier.
-
- @param handle
- */
-void
-trio_unregister
-TRIO_ARGS1((handle),
- trio_pointer_t handle)
-{
- trio_userdef_t *self = (trio_userdef_t *)handle;
- trio_userdef_t *def;
- trio_userdef_t *prev = NULL;
-
- assert(VALID(self));
-
- if (self->name)
- {
- def = TrioFindNamespace(self->name, &prev);
- if (def)
- {
- if (internalEnterCriticalRegion)
- (void)internalEnterCriticalRegion(NULL);
-
- if (prev == NULL)
- internalUserDef = NULL;
- else
- prev->next = def->next;
-
- if (internalLeaveCriticalRegion)
- (void)internalLeaveCriticalRegion(NULL);
- }
- trio_destroy(self->name);
- }
- TRIO_FREE(self);
-}
-
-/*************************************************************************
- * trio_get_format [public]
- */
-TRIO_CONST char *
-trio_get_format
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
-#if defined(FORMAT_USER_DEFINED)
- assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
-#endif
-
- return (((trio_reference_t *)ref)->parameter->user_data);
-}
-
-/*************************************************************************
- * trio_get_argument [public]
- */
-trio_pointer_t
-trio_get_argument
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
-#if defined(FORMAT_USER_DEFINED)
- assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
-#endif
-
- return ((trio_reference_t *)ref)->parameter->data.pointer;
-}
-
-/*************************************************************************
- * trio_get_width / trio_set_width [public]
- */
-int
-trio_get_width
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return ((trio_reference_t *)ref)->parameter->width;
-}
-
-void
-trio_set_width
-TRIO_ARGS2((ref, width),
- trio_pointer_t ref,
- int width)
-{
- ((trio_reference_t *)ref)->parameter->width = width;
-}
-
-/*************************************************************************
- * trio_get_precision / trio_set_precision [public]
- */
-int
-trio_get_precision
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->precision);
-}
-
-void
-trio_set_precision
-TRIO_ARGS2((ref, precision),
- trio_pointer_t ref,
- int precision)
-{
- ((trio_reference_t *)ref)->parameter->precision = precision;
-}
-
-/*************************************************************************
- * trio_get_base / trio_set_base [public]
- */
-int
-trio_get_base
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->base);
-}
-
-void
-trio_set_base
-TRIO_ARGS2((ref, base),
- trio_pointer_t ref,
- int base)
-{
- ((trio_reference_t *)ref)->parameter->base = base;
-}
-
-/*************************************************************************
- * trio_get_long / trio_set_long [public]
- */
-int
-trio_get_long
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_long
-TRIO_ARGS2((ref, is_long),
- trio_pointer_t ref,
- int is_long)
-{
- if (is_long)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG;
-}
-
-/*************************************************************************
- * trio_get_longlong / trio_set_longlong [public]
- */
-int
-trio_get_longlong
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_longlong
-TRIO_ARGS2((ref, is_longlong),
- trio_pointer_t ref,
- int is_longlong)
-{
- if (is_longlong)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD;
-}
-
-/*************************************************************************
- * trio_get_longdouble / trio_set_longdouble [public]
- */
-int
-trio_get_longdouble
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_longdouble
-TRIO_ARGS2((ref, is_longdouble),
- trio_pointer_t ref,
- int is_longdouble)
-{
- if (is_longdouble)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE;
-}
-
-/*************************************************************************
- * trio_get_short / trio_set_short [public]
- */
-int
-trio_get_short
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_short
-TRIO_ARGS2((ref, is_short),
- trio_pointer_t ref,
- int is_short)
-{
- if (is_short)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT;
-}
-
-/*************************************************************************
- * trio_get_shortshort / trio_set_shortshort [public]
- */
-int
-trio_get_shortshort
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_shortshort
-TRIO_ARGS2((ref, is_shortshort),
- trio_pointer_t ref,
- int is_shortshort)
-{
- if (is_shortshort)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT;
-}
-
-/*************************************************************************
- * trio_get_alternative / trio_set_alternative [public]
- */
-int
-trio_get_alternative
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_alternative
-TRIO_ARGS2((ref, is_alternative),
- trio_pointer_t ref,
- int is_alternative)
-{
- if (is_alternative)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE;
-}
-
-/*************************************************************************
- * trio_get_alignment / trio_set_alignment [public]
- */
-int
-trio_get_alignment
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_alignment
-TRIO_ARGS2((ref, is_leftaligned),
- trio_pointer_t ref,
- int is_leftaligned)
-{
- if (is_leftaligned)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST;
-}
-
-/*************************************************************************
- * trio_get_spacing /trio_set_spacing [public]
- */
-int
-trio_get_spacing
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_spacing
-TRIO_ARGS2((ref, is_space),
- trio_pointer_t ref,
- int is_space)
-{
- if (is_space)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE;
-}
-
-/*************************************************************************
- * trio_get_sign / trio_set_sign [public]
- */
-int
-trio_get_sign
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_sign
-TRIO_ARGS2((ref, is_sign),
- trio_pointer_t ref,
- int is_sign)
-{
- if (is_sign)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN;
-}
-
-/*************************************************************************
- * trio_get_padding / trio_set_padding [public]
- */
-int
-trio_get_padding
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_padding
-TRIO_ARGS2((ref, is_padding),
- trio_pointer_t ref,
- int is_padding)
-{
- if (is_padding)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING;
-}
-
-/*************************************************************************
- * trio_get_quote / trio_set_quote [public]
- */
-int
-trio_get_quote
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_quote
-TRIO_ARGS2((ref, is_quote),
- trio_pointer_t ref,
- int is_quote)
-{
- if (is_quote)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE;
-}
-
-/*************************************************************************
- * trio_get_upper / trio_set_upper [public]
- */
-int
-trio_get_upper
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_upper
-TRIO_ARGS2((ref, is_upper),
- trio_pointer_t ref,
- int is_upper)
-{
- if (is_upper)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER;
-}
-
-/*************************************************************************
- * trio_get_largest / trio_set_largest [public]
- */
-#if TRIO_C99
-int
-trio_get_largest
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_largest
-TRIO_ARGS2((ref, is_largest),
- trio_pointer_t ref,
- int is_largest)
-{
- if (is_largest)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T;
-}
-#endif
-
-/*************************************************************************
- * trio_get_ptrdiff / trio_set_ptrdiff [public]
- */
-int
-trio_get_ptrdiff
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_ptrdiff
-TRIO_ARGS2((ref, is_ptrdiff),
- trio_pointer_t ref,
- int is_ptrdiff)
-{
- if (is_ptrdiff)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T;
-}
-
-/*************************************************************************
- * trio_get_size / trio_set_size [public]
- */
-#if TRIO_C99
-int
-trio_get_size
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_size
-TRIO_ARGS2((ref, is_size),
- trio_pointer_t ref,
- int is_size)
-{
- if (is_size)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T;
-}
-#endif
-
-/*************************************************************************
- * trio_print_int [public]
- */
-void
-trio_print_int
-TRIO_ARGS2((ref, number),
- trio_pointer_t ref,
- int number)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteNumber(self->data,
- (trio_uintmax_t)number,
- self->parameter->flags,
- self->parameter->width,
- self->parameter->precision,
- self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_uint [public]
- */
-void
-trio_print_uint
-TRIO_ARGS2((ref, number),
- trio_pointer_t ref,
- unsigned int number)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteNumber(self->data,
- (trio_uintmax_t)number,
- self->parameter->flags | FLAGS_UNSIGNED,
- self->parameter->width,
- self->parameter->precision,
- self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_double [public]
- */
-void
-trio_print_double
-TRIO_ARGS2((ref, number),
- trio_pointer_t ref,
- double number)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteDouble(self->data,
- number,
- self->parameter->flags,
- self->parameter->width,
- self->parameter->precision,
- self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_string [public]
- */
-void
-trio_print_string
-TRIO_ARGS2((ref, string),
- trio_pointer_t ref,
- char *string)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteString(self->data,
- string,
- self->parameter->flags,
- self->parameter->width,
- self->parameter->precision);
-}
-
-/*************************************************************************
- * trio_print_ref [public]
- */
-int
-trio_print_ref
-TRIO_VARGS3((ref, format, va_alist),
- trio_pointer_t ref,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list arglist;
-
- assert(VALID(format));
-
- TRIO_VA_START(arglist, format);
- status = TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
- TRIO_VA_END(arglist);
- return status;
-}
-
-/*************************************************************************
- * trio_vprint_ref [public]
- */
-int
-trio_vprint_ref
-TRIO_ARGS3((ref, format, arglist),
- trio_pointer_t ref,
- TRIO_CONST char *format,
- va_list arglist)
-{
- assert(VALID(format));
-
- return TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
-}
-
-/*************************************************************************
- * trio_printv_ref [public]
- */
-int
-trio_printv_ref
-TRIO_ARGS3((ref, format, argarray),
- trio_pointer_t ref,
- TRIO_CONST char *format,
- trio_pointer_t *argarray)
-{
- assert(VALID(format));
-
- return TrioFormatRef((trio_reference_t *)ref, format, NULL, argarray);
-}
-
-#endif /* TRIO_EXTENSION */
-
-/*************************************************************************
- * trio_print_pointer [public]
- */
-void
-trio_print_pointer
-TRIO_ARGS2((ref, pointer),
- trio_pointer_t ref,
- trio_pointer_t pointer)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
- trio_flags_t flags;
- trio_uintmax_t number;
-
- if (NULL == pointer)
- {
- TRIO_CONST char *string = internalNullString;
- while (*string)
- self->data->OutStream(self->data, *string++);
- }
- else
- {
- /*
- * The subtraction of the null pointer is a workaround
- * to avoid a compiler warning. The performance overhead
- * is negligible (and likely to be removed by an
- * optimizing compiler). The (char *) casting is done
- * to please ANSI C++.
- */
- number = (trio_uintmax_t)((char *)pointer - (char *)0);
- /* Shrink to size of pointer */
- number &= (trio_uintmax_t)-1;
- flags = self->parameter->flags;
- flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE |
- FLAGS_NILPADDING);
- TrioWriteNumber(self->data,
- number,
- flags,
- POINTER_WIDTH,
- NO_PRECISION,
- BASE_HEX);
- }
-}
-
-/** @} End of UserDefined documentation module */
-
-/*************************************************************************
- *
- * LOCALES
- *
- ************************************************************************/
-
-/*************************************************************************
- * trio_locale_set_decimal_point
- *
- * Decimal point can only be one character. The input argument is a
- * string to enable multibyte characters. At most MB_LEN_MAX characters
- * will be used.
- */
-TRIO_PUBLIC void
-trio_locale_set_decimal_point
-TRIO_ARGS1((decimalPoint),
- char *decimalPoint)
-{
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
- internalDecimalPointLength = trio_length(decimalPoint);
- if (internalDecimalPointLength == 1)
- {
- internalDecimalPoint = *decimalPoint;
- }
- else
- {
- internalDecimalPoint = NIL;
- trio_copy_max(internalDecimalPointString,
- sizeof(internalDecimalPointString),
- decimalPoint);
- }
-}
-
-/*************************************************************************
- * trio_locale_set_thousand_separator
- *
- * See trio_locale_set_decimal_point
- */
-TRIO_PUBLIC void
-trio_locale_set_thousand_separator
-TRIO_ARGS1((thousandSeparator),
- char *thousandSeparator)
-{
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
- trio_copy_max(internalThousandSeparator,
- sizeof(internalThousandSeparator),
- thousandSeparator);
- internalThousandSeparatorLength = trio_length(internalThousandSeparator);
-}
-
-/*************************************************************************
- * trio_locale_set_grouping
- *
- * Array of bytes. Reversed order.
- *
- * CHAR_MAX : No further grouping
- * 0 : Repeat last group for the remaining digits (not necessary
- * as C strings are zero-terminated)
- * n : Set current group to n
- *
- * Same order as the grouping attribute in LC_NUMERIC.
- */
-TRIO_PUBLIC void
-trio_locale_set_grouping
-TRIO_ARGS1((grouping),
- char *grouping)
-{
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
- trio_copy_max(internalGrouping,
- sizeof(internalGrouping),
- grouping);
-}
-
-
-/*************************************************************************
- *
- * SCANNING
- *
- ************************************************************************/
-
-/*************************************************************************
- * TrioSkipWhitespaces
- */
-TRIO_PRIVATE int
-TrioSkipWhitespaces
-TRIO_ARGS1((self),
- trio_class_t *self)
-{
- int ch;
-
- ch = self->current;
- while (isspace(ch))
- {
- self->InStream(self, &ch);
- }
- return ch;
-}
-
-/*************************************************************************
- * TrioGetCollation
- */
-#if TRIO_EXTENSION
-TRIO_PRIVATE void
-TrioGetCollation(TRIO_NOARGS)
-{
- int i;
- int j;
- int k;
- char first[2];
- char second[2];
-
- /* This is computationally expensive */
- first[1] = NIL;
- second[1] = NIL;
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- {
- k = 0;
- first[0] = (char)i;
- for (j = 0; j < MAX_CHARACTER_CLASS; j++)
- {
- second[0] = (char)j;
- if (trio_equal_locale(first, second))
- internalCollationArray[i][k++] = (char)j;
- }
- internalCollationArray[i][k] = NIL;
- }
-}
-#endif
-
-/*************************************************************************
- * TrioGetCharacterClass
- *
- * FIXME:
- * multibyte
- */
-TRIO_PRIVATE int
-TrioGetCharacterClass
-TRIO_ARGS4((format, indexPointer, flagsPointer, characterclass),
- TRIO_CONST char *format,
- int *indexPointer,
- trio_flags_t *flagsPointer,
- int *characterclass)
-{
- int index = *indexPointer;
- int i;
- char ch;
- char range_begin;
- char range_end;
-
- *flagsPointer &= ~FLAGS_EXCLUDE;
-
- if (format[index] == QUALIFIER_CIRCUMFLEX)
- {
- *flagsPointer |= FLAGS_EXCLUDE;
- index++;
- }
- /*
- * If the ungroup character is at the beginning of the scanlist,
- * it will be part of the class, and a second ungroup character
- * must follow to end the group.
- */
- if (format[index] == SPECIFIER_UNGROUP)
- {
- characterclass[(int)SPECIFIER_UNGROUP]++;
- index++;
- }
- /*
- * Minus is used to specify ranges. To include minus in the class,
- * it must be at the beginning of the list
- */
- if (format[index] == QUALIFIER_MINUS)
- {
- characterclass[(int)QUALIFIER_MINUS]++;
- index++;
- }
- /* Collect characters */
- for (ch = format[index];
- (ch != SPECIFIER_UNGROUP) && (ch != NIL);
- ch = format[++index])
- {
- switch (ch)
- {
- case QUALIFIER_MINUS: /* Scanlist ranges */
-
- /*
- * Both C99 and UNIX98 describes ranges as implementation-
- * defined.
- *
- * We support the following behaviour (although this may
- * change as we become wiser)
- * - only increasing ranges, ie. [a-b] but not [b-a]
- * - transitive ranges, ie. [a-b-c] == [a-c]
- * - trailing minus, ie. [a-] is interpreted as an 'a'
- * and a '-'
- * - duplicates (although we can easily convert these
- * into errors)
- */
- range_begin = format[index - 1];
- range_end = format[++index];
- if (range_end == SPECIFIER_UNGROUP)
- {
- /* Trailing minus is included */
- characterclass[(int)ch]++;
- ch = range_end;
- break; /* for */
- }
- if (range_end == NIL)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- if (range_begin > range_end)
- return TRIO_ERROR_RETURN(TRIO_ERANGE, index);
-
- for (i = (int)range_begin; i <= (int)range_end; i++)
- characterclass[i]++;
-
- ch = range_end;
- break;
-
-#if TRIO_EXTENSION
-
- case SPECIFIER_GROUP:
-
- switch (format[index + 1])
- {
- case QUALIFIER_DOT: /* Collating symbol */
- /*
- * FIXME: This will be easier to implement when multibyte
- * characters have been implemented. Until now, we ignore
- * this feature.
- */
- for (i = index + 2; ; i++)
- {
- if (format[i] == NIL)
- /* Error in syntax */
- return -1;
- else if (format[i] == QUALIFIER_DOT)
- break; /* for */
- }
- if (format[++i] != SPECIFIER_UNGROUP)
- return -1;
-
- index = i;
- break;
-
- case QUALIFIER_EQUAL: /* Equivalence class expressions */
- {
- unsigned int j;
- unsigned int k;
-
- if (internalCollationUnconverted)
- {
- /* Lazy evaluation of collation array */
- TrioGetCollation();
- internalCollationUnconverted = FALSE;
- }
- for (i = index + 2; ; i++)
- {
- if (format[i] == NIL)
- /* Error in syntax */
- return -1;
- else if (format[i] == QUALIFIER_EQUAL)
- break; /* for */
- else
- {
- /* Mark any equivalent character */
- k = (unsigned int)format[i];
- for (j = 0; internalCollationArray[k][j] != NIL; j++)
- characterclass[(int)internalCollationArray[k][j]]++;
- }
- }
- if (format[++i] != SPECIFIER_UNGROUP)
- return -1;
-
- index = i;
- }
- break;
-
- case QUALIFIER_COLON: /* Character class expressions */
-
- if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isalnum(i))
- characterclass[i]++;
- index += sizeof(CLASS_ALNUM) - 1;
- }
- else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isalpha(i))
- characterclass[i]++;
- index += sizeof(CLASS_ALPHA) - 1;
- }
- else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (iscntrl(i))
- characterclass[i]++;
- index += sizeof(CLASS_CNTRL) - 1;
- }
- else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isdigit(i))
- characterclass[i]++;
- index += sizeof(CLASS_DIGIT) - 1;
- }
- else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isgraph(i))
- characterclass[i]++;
- index += sizeof(CLASS_GRAPH) - 1;
- }
- else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (islower(i))
- characterclass[i]++;
- index += sizeof(CLASS_LOWER) - 1;
- }
- else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isprint(i))
- characterclass[i]++;
- index += sizeof(CLASS_PRINT) - 1;
- }
- else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (ispunct(i))
- characterclass[i]++;
- index += sizeof(CLASS_PUNCT) - 1;
- }
- else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isspace(i))
- characterclass[i]++;
- index += sizeof(CLASS_SPACE) - 1;
- }
- else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isupper(i))
- characterclass[i]++;
- index += sizeof(CLASS_UPPER) - 1;
- }
- else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isxdigit(i))
- characterclass[i]++;
- index += sizeof(CLASS_XDIGIT) - 1;
- }
- else
- {
- characterclass[(int)ch]++;
- }
- break;
-
- default:
- characterclass[(int)ch]++;
- break;
- }
- break;
-
-#endif /* TRIO_EXTENSION */
-
- default:
- characterclass[(int)ch]++;
- break;
- }
- }
- return 0;
-}
-
-/*************************************************************************
- * TrioReadNumber
- *
- * We implement our own number conversion in preference of strtol and
- * strtoul, because we must handle 'long long' and thousand separators.
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadNumber
-TRIO_ARGS5((self, target, flags, width, base),
- trio_class_t *self,
- trio_uintmax_t *target,
- trio_flags_t flags,
- int width,
- int base)
-{
- trio_uintmax_t number = 0;
- int digit;
- int count;
- BOOLEAN_T isNegative = FALSE;
- BOOLEAN_T gotNumber = FALSE;
- int j;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
- assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE));
-
- if (internalDigitsUnconverted)
- {
- /* Lazy evaluation of digits array */
- memset(internalDigitArray, -1, sizeof(internalDigitArray));
- for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++)
- {
- internalDigitArray[(int)internalDigitsLower[j]] = j;
- internalDigitArray[(int)internalDigitsUpper[j]] = j;
- }
- internalDigitsUnconverted = FALSE;
- }
-
- TrioSkipWhitespaces(self);
-
- if (!(flags & FLAGS_UNSIGNED))
- {
- /* Leading sign */
- if (self->current == '+')
- {
- self->InStream(self, NULL);
- }
- else if (self->current == '-')
- {
- self->InStream(self, NULL);
- isNegative = TRUE;
- }
- }
-
- count = self->processed;
-
- if (flags & FLAGS_ALTERNATIVE)
- {
- switch (base)
- {
- case NO_BASE:
- case BASE_OCTAL:
- case BASE_HEX:
- case BASE_BINARY:
- if (self->current == '0')
- {
- self->InStream(self, NULL);
- if (self->current)
- {
- if ((base == BASE_HEX) &&
- (trio_to_upper(self->current) == 'X'))
- {
- self->InStream(self, NULL);
- }
- else if ((base == BASE_BINARY) &&
- (trio_to_upper(self->current) == 'B'))
- {
- self->InStream(self, NULL);
- }
- }
- }
- else
- return FALSE;
- break;
- default:
- break;
- }
- }
-
- while (((width == NO_WIDTH) || (self->processed - count < width)) &&
- (! ((self->current == EOF) || isspace(self->current))))
- {
- if (isascii(self->current))
- {
- digit = internalDigitArray[self->current];
- /* Abort if digit is not allowed in the specified base */
- if ((digit == -1) || (digit >= base))
- break;
- }
- else if (flags & FLAGS_QUOTE)
- {
- /* Compare with thousands separator */
- for (j = 0; internalThousandSeparator[j] && self->current; j++)
- {
- if (internalThousandSeparator[j] != self->current)
- break;
-
- self->InStream(self, NULL);
- }
- if (internalThousandSeparator[j])
- break; /* Mismatch */
- else
- continue; /* Match */
- }
- else
- break;
-
- number *= base;
- number += digit;
- gotNumber = TRUE; /* we need at least one digit */
-
- self->InStream(self, NULL);
- }
-
- /* Was anything read at all? */
- if (!gotNumber)
- return FALSE;
-
- if (target)
- *target = (isNegative) ? -((trio_intmax_t)number) : number;
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadChar
- */
-TRIO_PRIVATE int
-TrioReadChar
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- char *target,
- trio_flags_t flags,
- int width)
-{
- int i;
- char ch;
- trio_uintmax_t number;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- for (i = 0;
- (self->current != EOF) && (i < width);
- i++)
- {
- ch = (char)self->current;
- self->InStream(self, NULL);
- if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH))
- {
- switch (self->current)
- {
- case '\\': ch = '\\'; break;
- case 'a': ch = '\007'; break;
- case 'b': ch = '\b'; break;
- case 'f': ch = '\f'; break;
- case 'n': ch = '\n'; break;
- case 'r': ch = '\r'; break;
- case 't': ch = '\t'; break;
- case 'v': ch = '\v'; break;
- default:
- if (isdigit(self->current))
- {
- /* Read octal number */
- if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL))
- return 0;
- ch = (char)number;
- }
- else if (trio_to_upper(self->current) == 'X')
- {
- /* Read hexadecimal number */
- self->InStream(self, NULL);
- if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX))
- return 0;
- ch = (char)number;
- }
- else
- {
- ch = (char)self->current;
- }
- break;
- }
- }
-
- if (target)
- target[i] = ch;
- }
- return i + 1;
-}
-
-/*************************************************************************
- * TrioReadString
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadString
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- char *target,
- trio_flags_t flags,
- int width)
-{
- int i;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- TrioSkipWhitespaces(self);
-
- /*
- * Continue until end of string is reached, a whitespace is encountered,
- * or width is exceeded
- */
- for (i = 0;
- ((width == NO_WIDTH) || (i < width)) &&
- (! ((self->current == EOF) || isspace(self->current)));
- i++)
- {
- if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0)
- break; /* for */
- }
- if (target)
- target[i] = NIL;
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadWideChar
- */
-#if TRIO_WIDECHAR
-TRIO_PRIVATE int
-TrioReadWideChar
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- trio_wchar_t *target,
- trio_flags_t flags,
- int width)
-{
- int i;
- int j;
- int size;
- int amount = 0;
- trio_wchar_t wch;
- char buffer[MB_LEN_MAX + 1];
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- for (i = 0;
- (self->current != EOF) && (i < width);
- i++)
- {
- if (isascii(self->current))
- {
- if (TrioReadChar(self, buffer, flags, 1) == 0)
- return 0;
- buffer[1] = NIL;
- }
- else
- {
- /*
- * Collect a multibyte character, by enlarging buffer until
- * it contains a fully legal multibyte character, or the
- * buffer is full.
- */
- j = 0;
- do
- {
- buffer[j++] = (char)self->current;
- buffer[j] = NIL;
- self->InStream(self, NULL);
- }
- while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j));
- }
- if (target)
- {
- size = mbtowc(&wch, buffer, sizeof(buffer));
- if (size > 0)
- target[i] = wch;
- }
- amount += size;
- self->InStream(self, NULL);
- }
- return amount;
-}
-#endif /* TRIO_WIDECHAR */
-
-/*************************************************************************
- * TrioReadWideString
- */
-#if TRIO_WIDECHAR
-TRIO_PRIVATE BOOLEAN_T
-TrioReadWideString
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- trio_wchar_t *target,
- trio_flags_t flags,
- int width)
-{
- int i;
- int size;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- TrioSkipWhitespaces(self);
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- /*
- * Continue until end of string is reached, a whitespace is encountered,
- * or width is exceeded
- */
- for (i = 0;
- ((width == NO_WIDTH) || (i < width)) &&
- (! ((self->current == EOF) || isspace(self->current)));
- )
- {
- size = TrioReadWideChar(self, &target[i], flags, 1);
- if (size == 0)
- break; /* for */
-
- i += size;
- }
- if (target)
- target[i] = WCONST('\0');
- return TRUE;
-}
-#endif /* TRIO_WIDECHAR */
-
-/*************************************************************************
- * TrioReadGroup
- *
- * FIXME: characterclass does not work with multibyte characters
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadGroup
-TRIO_ARGS5((self, target, characterclass, flags, width),
- trio_class_t *self,
- char *target,
- int *characterclass,
- trio_flags_t flags,
- int width)
-{
- int ch;
- int i;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- ch = self->current;
- for (i = 0;
- ((width == NO_WIDTH) || (i < width)) &&
- (! ((ch == EOF) ||
- (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0))));
- i++)
- {
- if (target)
- target[i] = (char)ch;
- self->InStream(self, &ch);
- }
-
- if (target)
- target[i] = NIL;
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadDouble
- *
- * FIXME:
- * add long double
- * handle base
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadDouble
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- trio_pointer_t target,
- trio_flags_t flags,
- int width)
-{
- int ch;
- char doubleString[512];
- int index = 0;
- int start;
- int j;
- BOOLEAN_T isHex = FALSE;
-
- doubleString[0] = 0;
-
- if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1))
- width = sizeof(doubleString) - 1;
-
- TrioSkipWhitespaces(self);
-
- /*
- * Read entire double number from stream. trio_to_double requires
- * a string as input, but InStream can be anything, so we have to
- * collect all characters.
- */
- ch = self->current;
- if ((ch == '+') || (ch == '-'))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- width--;
- }
-
- start = index;
- switch (ch)
- {
- case 'n':
- case 'N':
- /* Not-a-number */
- if (index != 0)
- break;
- /* FALLTHROUGH */
- case 'i':
- case 'I':
- /* Infinity */
- while (isalpha(ch) && (index - start < width))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- doubleString[index] = NIL;
-
- /* Case insensitive string comparison */
- if (trio_equal(&doubleString[start], INFINITE_UPPER) ||
- trio_equal(&doubleString[start], LONG_INFINITE_UPPER))
- {
- if (flags & FLAGS_LONGDOUBLE)
- {
- if ((start == 1) && (doubleString[0] == '-'))
- {
- *((trio_long_double_t *)target) = trio_ninf();
- }
- else
- {
- *((trio_long_double_t *)target) = trio_pinf();
- }
- }
- else
- {
- if ((start == 1) && (doubleString[0] == '-'))
- {
- *((double *)target) = trio_ninf();
- }
- else
- {
- *((double *)target) = trio_pinf();
- }
- }
- return TRUE;
- }
- if (trio_equal(doubleString, NAN_UPPER))
- {
- /* NaN must not have a preceding + nor - */
- if (flags & FLAGS_LONGDOUBLE)
- {
- *((trio_long_double_t *)target) = trio_nan();
- }
- else
- {
- *((double *)target) = trio_nan();
- }
- return TRUE;
- }
- return FALSE;
-
- case '0':
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- if (trio_to_upper(ch) == 'X')
- {
- isHex = TRUE;
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- break;
-
- default:
- break;
- }
-
- while ((ch != EOF) && (index - start < width))
- {
- /* Integer part */
- if (isHex ? isxdigit(ch) : isdigit(ch))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- else if (flags & FLAGS_QUOTE)
- {
- /* Compare with thousands separator */
- for (j = 0; internalThousandSeparator[j] && self->current; j++)
- {
- if (internalThousandSeparator[j] != self->current)
- break;
-
- self->InStream(self, &ch);
- }
- if (internalThousandSeparator[j])
- break; /* Mismatch */
- else
- continue; /* Match */
- }
- else
- break; /* while */
- }
- if (ch == '.')
- {
- /* Decimal part */
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- while ((isHex ? isxdigit(ch) : isdigit(ch)) &&
- (index - start < width))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- if (isHex ? (trio_to_upper(ch) == 'P') : (trio_to_upper(ch) == 'E'))
- {
- /* Exponent */
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- if ((ch == '+') || (ch == '-'))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- while (isdigit(ch) && (index - start < width))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- }
- }
-
- if ((index == start) || (*doubleString == NIL))
- return FALSE;
-
- doubleString[index] = 0;
-
- if (flags & FLAGS_LONGDOUBLE)
- {
- *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL);
- }
- else
- {
- *((double *)target) = trio_to_double(doubleString, NULL);
- }
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadPointer
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadPointer
-TRIO_ARGS3((self, target, flags),
- trio_class_t *self,
- trio_pointer_t *target,
- trio_flags_t flags)
-{
- trio_uintmax_t number;
- char buffer[sizeof(internalNullString)];
-
- flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING);
-
- if (TrioReadNumber(self,
- &number,
- flags,
- POINTER_WIDTH,
- BASE_HEX))
- {
- /*
- * The strange assignment of number is a workaround for a compiler
- * warning
- */
- if (target)
- *target = (char *)0 + number;
- return TRUE;
- }
- else if (TrioReadString(self,
- (flags & FLAGS_IGNORE)
- ? NULL
- : buffer,
- 0,
- sizeof(internalNullString) - 1))
- {
- if (trio_equal_case(buffer, internalNullString))
- {
- if (target)
- *target = NULL;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/*************************************************************************
- * TrioScanProcess
- */
-TRIO_PRIVATE int
-TrioScanProcess
-TRIO_ARGS3((data, format, parameters),
- trio_class_t *data,
- TRIO_CONST char *format,
- trio_parameter_t *parameters)
-{
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- int charlen;
- int cnt;
-#endif
- int assignment;
- int ch;
- int index; /* Index of format string */
- int i; /* Index of current parameter */
- trio_flags_t flags;
- int width;
- int base;
- trio_pointer_t pointer;
-
- assignment = 0;
- i = 0;
- index = 0;
- data->InStream(data, &ch);
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- while (format[index])
- {
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- if (! isascii(format[index]))
- {
- charlen = mblen(&format[index], MB_LEN_MAX);
- if (charlen != -1)
- {
- /* Compare multibyte characters in format string */
- for (cnt = 0; cnt < charlen - 1; cnt++)
- {
- if (ch != format[index + cnt])
- {
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- data->InStream(data, &ch);
- }
- continue; /* while characters left in formatting string */
- }
- }
-#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
-
- if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
- {
- return (assignment > 0) ? assignment : EOF;
- }
-
- if (CHAR_IDENTIFIER == format[index])
- {
- if (CHAR_IDENTIFIER == format[index + 1])
- {
- /* Two % in format matches one % in input stream */
- if (CHAR_IDENTIFIER == ch)
- {
- data->InStream(data, &ch);
- index += 2;
- continue; /* while format chars left */
- }
- else
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
-
- /* Skip the parameter entries */
- while (parameters[i].type == FORMAT_PARAMETER)
- i++;
-
- flags = parameters[i].flags;
- /* Find width */
- width = parameters[i].width;
- if (flags & FLAGS_WIDTH_PARAMETER)
- {
- /* Get width from parameter list */
- width = (int)parameters[width].data.number.as_signed;
- }
- /* Find base */
- base = parameters[i].base;
- if (flags & FLAGS_BASE_PARAMETER)
- {
- /* Get base from parameter list */
- base = (int)parameters[base].data.number.as_signed;
- }
-
- switch (parameters[i].type)
- {
- case FORMAT_INT:
- {
- trio_uintmax_t number;
-
- if (0 == base)
- base = BASE_DECIMAL;
-
- if (!TrioReadNumber(data,
- &number,
- flags,
- width,
- base))
- return assignment;
-
- if (!(flags & FLAGS_IGNORE))
- {
- assignment++;
-
- pointer = parameters[i].data.pointer;
-#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
- if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)number;
- else
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)number;
- else
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)number;
- else
-#endif
- if (flags & FLAGS_QUAD)
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number;
- else if (flags & FLAGS_LONG)
- *(long int *)pointer = (long int)number;
- else if (flags & FLAGS_SHORT)
- *(short int *)pointer = (short int)number;
- else
- *(int *)pointer = (int)number;
- }
- }
- break; /* FORMAT_INT */
-
- case FORMAT_STRING:
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- if (!TrioReadWideString(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.wstring,
- flags,
- width))
- return assignment;
- }
- else
-#endif
- {
- if (!TrioReadString(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.string,
- flags,
- width))
- return assignment;
- }
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- break; /* FORMAT_STRING */
-
- case FORMAT_DOUBLE:
- {
- trio_pointer_t pointer;
-
- if (flags & FLAGS_IGNORE)
- {
- pointer = NULL;
- }
- else
- {
- pointer = (flags & FLAGS_LONGDOUBLE)
- ? (trio_pointer_t)parameters[i].data.longdoublePointer
- : (trio_pointer_t)parameters[i].data.doublePointer;
- }
- if (!TrioReadDouble(data, pointer, flags, width))
- {
- return assignment;
- }
- if (!(flags & FLAGS_IGNORE))
- {
- assignment++;
- }
- break; /* FORMAT_DOUBLE */
- }
- case FORMAT_GROUP:
- {
- int characterclass[MAX_CHARACTER_CLASS + 1];
- int rc;
-
- /* Skip over modifiers */
- while (format[index] != SPECIFIER_GROUP)
- {
- index++;
- }
- /* Skip over group specifier */
- index++;
-
- memset(characterclass, 0, sizeof(characterclass));
- rc = TrioGetCharacterClass(format,
- &index,
- &flags,
- characterclass);
- if (rc < 0)
- return rc;
-
- if (!TrioReadGroup(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.string,
- characterclass,
- flags,
- parameters[i].width))
- return assignment;
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- }
- break; /* FORMAT_GROUP */
-
- case FORMAT_COUNT:
- pointer = parameters[i].data.pointer;
- if (NULL != pointer)
- {
- int count = data->committed;
- if (ch != EOF)
- count--; /* a character is read, but is not consumed yet */
-#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
- if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)count;
- else
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)count;
- else
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)count;
- else
-#endif
- if (flags & FLAGS_QUAD)
- {
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;
- }
- else if (flags & FLAGS_LONG)
- {
- *(long int *)pointer = (long int)count;
- }
- else if (flags & FLAGS_SHORT)
- {
- *(short int *)pointer = (short int)count;
- }
- else
- {
- *(int *)pointer = (int)count;
- }
- }
- break; /* FORMAT_COUNT */
-
- case FORMAT_CHAR:
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- if (TrioReadWideChar(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.wstring,
- flags,
- (width == NO_WIDTH) ? 1 : width) == 0)
- return assignment;
- }
- else
-#endif
- {
- if (TrioReadChar(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.string,
- flags,
- (width == NO_WIDTH) ? 1 : width) == 0)
- return assignment;
- }
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- break; /* FORMAT_CHAR */
-
- case FORMAT_POINTER:
- if (!TrioReadPointer(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : (trio_pointer_t *)parameters[i].data.pointer,
- flags))
- return assignment;
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- break; /* FORMAT_POINTER */
-
- case FORMAT_PARAMETER:
- break; /* FORMAT_PARAMETER */
-
- default:
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- ch = data->current;
- index = parameters[i].indexAfterSpecifier;
- i++;
- }
- else /* Not an % identifier */
- {
- if (isspace((int)format[index]))
- {
- /* Whitespaces may match any amount of whitespaces */
- ch = TrioSkipWhitespaces(data);
- }
- else if (ch == format[index])
- {
- data->InStream(data, &ch);
- }
- else
- return assignment;
-
- index++;
- }
- }
- return assignment;
-}
-
-/*************************************************************************
- * TrioScan
- */
-TRIO_PRIVATE int
-TrioScan
-TRIO_ARGS6((source, sourceSize, InStream, format, arglist, argarray),
- trio_pointer_t source,
- size_t sourceSize,
- void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
- TRIO_CONST char *format,
- TRIO_VA_LIST_PTR arglist,
- trio_pointer_t *argarray)
-{
- int status;
- trio_parameter_t parameters[MAX_PARAMETERS];
- trio_class_t data;
-
- assert(VALID(InStream));
- assert(VALID(format));
-
- memset(&data, 0, sizeof(data));
- data.InStream = InStream;
- data.location = (trio_pointer_t)source;
- data.max = sourceSize;
- data.error = 0;
-
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
-
- status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray);
- if (status < 0)
- return status;
-
- status = TrioScanProcess(&data, format, parameters);
- if (data.error != 0)
- {
- status = data.error;
- }
- return status;
-}
-
-/*************************************************************************
- * TrioInStreamFile
- */
-TRIO_PRIVATE void
-TrioInStreamFile
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- FILE *file;
-
- assert(VALID(self));
- assert(VALID(self->location));
- assert(VALID(file));
-
- file = (FILE *)self->location;
-
- self->current = fgetc(file);
- if (self->current == EOF)
- {
- self->error = (ferror(file))
- ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0)
- : TRIO_ERROR_RETURN(TRIO_EOF, 0);
- }
- else
- {
- self->processed++;
- self->committed++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-
-/*************************************************************************
- * TrioInStreamFileDescriptor
- */
-TRIO_PRIVATE void
-TrioInStreamFileDescriptor
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- int fd;
- int size;
- unsigned char input;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- fd = *((int *)self->location);
-
- size = read(fd, &input, sizeof(char));
- if (size == -1)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
- self->current = EOF;
- }
- else
- {
- self->current = (size == 0) ? EOF : input;
- }
- if (self->current != EOF)
- {
- self->committed++;
- self->processed++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-
-/*************************************************************************
- * TrioInStreamCustom
- */
-TRIO_PRIVATE void
-TrioInStreamCustom
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- trio_custom_t *data;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- data = (trio_custom_t *)self->location;
-
- self->current = (data->stream.in == NULL)
- ? NIL
- : (data->stream.in)(data->closure);
-
- if (self->current == NIL)
- {
- self->current = EOF;
- }
- else
- {
- self->processed++;
- self->committed++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-
-/*************************************************************************
- * TrioInStreamString
- */
-TRIO_PRIVATE void
-TrioInStreamString
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- unsigned char **buffer;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- buffer = (unsigned char **)self->location;
- self->current = (*buffer)[0];
- if (self->current == NIL)
- {
- self->current = EOF;
- }
- else
- {
- (*buffer)++;
- self->processed++;
- self->committed++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-
-/*************************************************************************
- *
- * Formatted scanning functions
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_scanf.h"
-#endif
-/** @addtogroup Scanf
- @{
-*/
-
-/*************************************************************************
- * scanf
- */
-
-/**
- Scan characters from standard input stream.
-
- @param format Formatting string.
- @param ... Arguments.
- @return Number of scanned characters.
- */
-TRIO_PUBLIC int
-trio_scanf
-TRIO_VARGS2((format, va_alist),
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)stdin, 0,
- TrioInStreamFile,
- format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vscanf
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)stdin, 0,
- TrioInStreamFile,
- format, TRIO_VA_LIST_ADDR(args), NULL);
-}
-
-TRIO_PUBLIC int
-trio_scanfv
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)stdin, 0,
- TrioInStreamFile,
- format, NULL, args);
-}
-
-/*************************************************************************
- * fscanf
- */
-TRIO_PUBLIC int
-trio_fscanf
-TRIO_VARGS3((file, format, va_alist),
- FILE *file,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(file));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)file, 0,
- TrioInStreamFile,
- format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vfscanf
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)file, 0,
- TrioInStreamFile,
- format, TRIO_VA_LIST_ADDR(args), NULL);
-}
-
-TRIO_PUBLIC int
-trio_fscanfv
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)file, 0,
- TrioInStreamFile,
- format, NULL, args);
-}
-
-/*************************************************************************
- * dscanf
- */
-TRIO_PUBLIC int
-trio_dscanf
-TRIO_VARGS3((fd, format, va_alist),
- int fd,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)&fd, 0,
- TrioInStreamFileDescriptor,
- format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vdscanf
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&fd, 0,
- TrioInStreamFileDescriptor,
- format, TRIO_VA_LIST_ADDR(args), NULL);
-}
-
-TRIO_PUBLIC int
-trio_dscanfv
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&fd, 0,
- TrioInStreamFileDescriptor,
- format, NULL, args);
-}
-
-/*************************************************************************
- * cscanf
- */
-TRIO_PUBLIC int
-trio_cscanf
-TRIO_VARGS4((stream, closure, format, va_alist),
- trio_instream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- data.stream.in = stream;
- data.closure = closure;
- status = TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vcscanf
-TRIO_ARGS4((stream, closure, format, args),
- trio_instream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- va_list args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.in = stream;
- data.closure = closure;
- return TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
-}
-
-TRIO_PUBLIC int
-trio_cscanfv
-TRIO_ARGS4((stream, closure, format, args),
- trio_instream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.in = stream;
- data.closure = closure;
- return TrioScan(&data, 0, TrioInStreamCustom, format, NULL, args);
-}
-
-/*************************************************************************
- * sscanf
- */
-TRIO_PUBLIC int
-trio_sscanf
-TRIO_VARGS3((buffer, format, va_alist),
- TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)&buffer, 0,
- TrioInStreamString,
- format, TRIO_VA_LIST_ADDR(args), NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vsscanf
-TRIO_ARGS3((buffer, format, args),
- TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(buffer));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&buffer, 0,
- TrioInStreamString,
- format, TRIO_VA_LIST_ADDR(args), NULL);
-}
-
-TRIO_PUBLIC int
-trio_sscanfv
-TRIO_ARGS3((buffer, format, args),
- TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(buffer));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&buffer, 0,
- TrioInStreamString,
- format, NULL, args);
-}
-
-/** @} End of Scanf documentation module */
-
-/*************************************************************************
- * trio_strerror
- */
-TRIO_PUBLIC TRIO_CONST char *
-trio_strerror
-TRIO_ARGS1((errorcode),
- int errorcode)
-{
- /* Textual versions of the error codes */
- switch (TRIO_ERROR_CODE(errorcode))
- {
- case TRIO_EOF:
- return "End of file";
- case TRIO_EINVAL:
- return "Invalid argument";
- case TRIO_ETOOMANY:
- return "Too many arguments";
- case TRIO_EDBLREF:
- return "Double reference";
- case TRIO_EGAP:
- return "Reference gap";
- case TRIO_ENOMEM:
- return "Out of memory";
- case TRIO_ERANGE:
- return "Invalid range";
- case TRIO_ECUSTOM:
- return "Custom error";
- default:
- return "Unknown";
- }
-}
diff --git a/trio.h b/trio.h
deleted file mode 100644
index dcf96b6..0000000
--- a/trio.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- *************************************************************************
- *
- * http://ctrio.sourceforge.net/
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIO_H
-#define TRIO_TRIO_H
-
-#if !defined(WITHOUT_TRIO)
-
-/*
- * Use autoconf defines if present. Packages using trio must define
- * HAVE_CONFIG_H as a compiler option themselves.
- */
-#if defined(TRIO_HAVE_CONFIG_H)
-# include "config.h"
-#endif
-
-#include "triodef.h"
-
-#include
-#include
-#if defined(TRIO_COMPILER_ANCIENT)
-# include
-#else
-# include
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Error codes.
- *
- * Remember to add a textual description to trio_strerror.
- */
-enum {
- TRIO_EOF = 1,
- TRIO_EINVAL = 2,
- TRIO_ETOOMANY = 3,
- TRIO_EDBLREF = 4,
- TRIO_EGAP = 5,
- TRIO_ENOMEM = 6,
- TRIO_ERANGE = 7,
- TRIO_ERRNO = 8,
- TRIO_ECUSTOM = 9
-};
-
-/* Error macros */
-#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF)
-#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8)
-#define TRIO_ERROR_NAME(x) trio_strerror(x)
-
-typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int));
-typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t));
-
-TRIO_CONST char *trio_strerror TRIO_PROTO((int));
-
-/*************************************************************************
- * Print Functions
- */
-
-int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...));
-int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args));
-
-int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
-int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
-int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-
-int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
-int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
-int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-
-int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, ...));
-int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, va_list args));
-int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, void **args));
-
-int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...));
-int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args));
-int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args));
-
-int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
-int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
- va_list args));
-int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
- void **args));
-
-int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
-int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
- va_list args));
-
-char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...));
-char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-
-int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...));
-int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args));
-
-/*************************************************************************
- * Scan Functions
- */
-int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...));
-int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args));
-
-int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
-int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
-int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-
-int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
-int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
-int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-
-int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, ...));
-int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, va_list args));
-int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, void **args));
-
-int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...));
-int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args));
-int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args));
-
-/*************************************************************************
- * Locale Functions
- */
-void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint));
-void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator));
-void trio_locale_set_grouping TRIO_PROTO((char *grouping));
-
-/*************************************************************************
- * Renaming
- */
-#ifdef TRIO_REPLACE_STDIO
-/* Replace the functions */
-#ifndef HAVE_PRINTF
-# undef printf
-# define printf trio_printf
-#endif
-#ifndef HAVE_VPRINTF
-# undef vprintf
-# define vprintf trio_vprintf
-#endif
-#ifndef HAVE_FPRINTF
-# undef fprintf
-# define fprintf trio_fprintf
-#endif
-#ifndef HAVE_VFPRINTF
-# undef vfprintf
-# define vfprintf trio_vfprintf
-#endif
-#ifndef HAVE_SPRINTF
-# undef sprintf
-# define sprintf trio_sprintf
-#endif
-#ifndef HAVE_VSPRINTF
-# undef vsprintf
-# define vsprintf trio_vsprintf
-#endif
-#ifndef HAVE_SNPRINTF
-# undef snprintf
-# define snprintf trio_snprintf
-#endif
-#ifndef HAVE_VSNPRINTF
-# undef vsnprintf
-# define vsnprintf trio_vsnprintf
-#endif
-#ifndef HAVE_SCANF
-# undef scanf
-# define scanf trio_scanf
-#endif
-#ifndef HAVE_VSCANF
-# undef vscanf
-# define vscanf trio_vscanf
-#endif
-#ifndef HAVE_FSCANF
-# undef fscanf
-# define fscanf trio_fscanf
-#endif
-#ifndef HAVE_VFSCANF
-# undef vfscanf
-# define vfscanf trio_vfscanf
-#endif
-#ifndef HAVE_SSCANF
-# undef sscanf
-# define sscanf trio_sscanf
-#endif
-#ifndef HAVE_VSSCANF
-# undef vsscanf
-# define vsscanf trio_vsscanf
-#endif
-/* These aren't stdio functions, but we make them look similar */
-#define dprintf trio_dprintf
-#define vdprintf trio_vdprintf
-#define aprintf trio_aprintf
-#define vaprintf trio_vaprintf
-#define asprintf trio_asprintf
-#define vasprintf trio_vasprintf
-#define dscanf trio_dscanf
-#define vdscanf trio_vdscanf
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* WITHOUT_TRIO */
-
-#endif /* TRIO_TRIO_H */
diff --git a/triodef.h b/triodef.h
deleted file mode 100644
index e101f6d..0000000
--- a/triodef.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIODEF_H
-#define TRIO_TRIODEF_H
-
-/*************************************************************************
- * Platform and compiler support detection
- */
-#if defined(__GNUC__)
-# define TRIO_COMPILER_GCC
-#elif defined(__SUNPRO_C)
-# define TRIO_COMPILER_SUNPRO
-#elif defined(__SUNPRO_CC)
-# define TRIO_COMPILER_SUNPRO
-# define __SUNPRO_C __SUNPRO_CC
-#elif defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__)
-# define TRIO_COMPILER_XLC
-#elif defined(_AIX) && !defined(__GNUC__)
-# define TRIO_COMPILER_XLC /* Workaround for old xlc */
-#elif defined(__DECC) || defined(__DECCXX)
-# define TRIO_COMPILER_DECC
-#elif defined(__osf__) && defined(__LANGUAGE_C__)
-# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */
-#elif defined(_MSC_VER)
-# define TRIO_COMPILER_MSVC
-#elif defined(__BORLANDC__)
-# define TRIO_COMPILER_BCB
-#endif
-
-#if defined(VMS) || defined(__VMS)
-/*
- * VMS is placed first to avoid identifying the platform as Unix
- * based on the DECC compiler later on.
- */
-# define TRIO_PLATFORM_VMS
-#elif defined(__OS400__)
-# define TRIO_PLATFORM_OS400
-#elif defined(unix) || defined(__unix) || defined(__unix__)
-# define TRIO_PLATFORM_UNIX
-#elif defined(TRIO_COMPILER_XLC) || defined(_AIX)
-# define TRIO_PLATFORM_UNIX
-#elif defined(TRIO_COMPILER_DECC) || defined(__osf___)
-# define TRIO_PLATFORM_UNIX
-#elif defined(__NetBSD__)
-# define TRIO_PLATFORM_UNIX
-#elif defined(__Lynx__)
-# define TRIO_PLATFORM_UNIX
-#elif defined(__QNX__)
-# define TRIO_PLATFORM_UNIX
-# define TRIO_PLATFORM_QNX
-#elif defined(__CYGWIN__)
-# define TRIO_PLATFORM_UNIX
-#elif defined(AMIGA) && defined(TRIO_COMPILER_GCC)
-# define TRIO_PLATFORM_UNIX
-#elif defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32)
-# define TRIO_PLATFORM_WIN32
-#elif defined(mpeix) || defined(__mpexl)
-# define TRIO_PLATFORM_MPEIX
-#endif
-
-#if defined(_AIX)
-# define TRIO_PLATFORM_AIX
-#elif defined(__hpux)
-# define TRIO_PLATFORM_HPUX
-#elif defined(sun) || defined(__sun__)
-# if defined(__SVR4) || defined(__svr4__)
-# define TRIO_PLATFORM_SOLARIS
-# else
-# define TRIO_PLATFORM_SUNOS
-# endif
-#endif
-
-#if defined(__STDC__) || defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
-# define TRIO_COMPILER_SUPPORTS_C89
-# if defined(__STDC_VERSION__)
-# define TRIO_COMPILER_SUPPORTS_C90
-# if (__STDC_VERSION__ >= 199409L)
-# define TRIO_COMPILER_SUPPORTS_C94
-# endif
-# if (__STDC_VERSION__ >= 199901L)
-# define TRIO_COMPILER_SUPPORTS_C99
-# endif
-# elif defined(TRIO_COMPILER_SUNPRO)
-# if (__SUNPRO_C >= 0x420)
-# define TRIO_COMPILER_SUPPORTS_C94
-# endif
-# endif
-#elif defined(TRIO_COMPILER_XLC) && defined(__EXTENDED__)
-# define TRIO_COMPILER_SUPPORTS_C89
-# define TRIO_COMPILER_SUPPORTS_C90
-# define TRIO_COMPILER_SUPPORTS_C94
-#endif
-
-#if defined(_XOPEN_SOURCE)
-# if defined(_XOPEN_SOURCE_EXTENDED)
-# define TRIO_COMPILER_SUPPORTS_UNIX95
-# endif
-# if (_XOPEN_VERSION >= 500)
-# define TRIO_COMPILER_SUPPORTS_UNIX98
-# endif
-# if (_XOPEN_VERSION >= 600)
-# define TRIO_COMPILER_SUPPORTS_UNIX01
-# endif
-#endif
-
-/*************************************************************************
- * Generic defines
- */
-
-#if !defined(TRIO_PUBLIC)
-# define TRIO_PUBLIC
-#endif
-#if !defined(TRIO_PRIVATE)
-# define TRIO_PRIVATE static
-#endif
-
-#if !(defined(TRIO_COMPILER_SUPPORTS_C89) || defined(__cplusplus))
-# define TRIO_COMPILER_ANCIENT
-#endif
-
-#if defined(TRIO_COMPILER_ANCIENT)
-# define TRIO_CONST
-# define TRIO_VOLATILE
-# define TRIO_SIGNED
-typedef double trio_long_double_t;
-typedef char * trio_pointer_t;
-# define TRIO_SUFFIX_LONG(x) x
-# define TRIO_PROTO(x) ()
-# define TRIO_NOARGS
-# define TRIO_ARGS1(list,a1) list a1;
-# define TRIO_ARGS2(list,a1,a2) list a1; a2;
-# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3;
-# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4;
-# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5;
-# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6;
-# define TRIO_VARGS2(list,a1,a2) list a1; a2
-# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3
-# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4
-# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5
-# define TRIO_VA_DECL va_dcl
-# define TRIO_VA_START(x,y) va_start(x)
-# define TRIO_VA_END(x) va_end(x)
-#else /* ANSI C */
-# define TRIO_CONST const
-# define TRIO_VOLATILE volatile
-# define TRIO_SIGNED signed
-typedef long double trio_long_double_t;
-typedef void * trio_pointer_t;
-# define TRIO_SUFFIX_LONG(x) x ## L
-# define TRIO_PROTO(x) x
-# define TRIO_NOARGS void
-# define TRIO_ARGS1(list,a1) (a1)
-# define TRIO_ARGS2(list,a1,a2) (a1,a2)
-# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3)
-# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4)
-# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5)
-# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6)
-# define TRIO_VARGS2 TRIO_ARGS2
-# define TRIO_VARGS3 TRIO_ARGS3
-# define TRIO_VARGS4 TRIO_ARGS4
-# define TRIO_VARGS5 TRIO_ARGS5
-# define TRIO_VA_DECL ...
-# define TRIO_VA_START(x,y) va_start(x,y)
-# define TRIO_VA_END(x) va_end(x)
-#endif
-
-#if defined(TRIO_COMPILER_SUPPORTS_C99) || defined(__cplusplus)
-# define TRIO_INLINE inline
-#elif defined(TRIO_COMPILER_GCC)
-# define TRIO_INLINE __inline__
-#elif defined(TRIO_COMPILER_MSVC)
-# define TRIO_INLINE _inline
-#elif defined(TRIO_COMPILER_BCB)
-# define TRIO_INLINE __inline
-#else
-# define TRIO_INLINE
-#endif
-
-/*************************************************************************
- * Workarounds
- */
-
-#if defined(TRIO_PLATFORM_VMS)
-/*
- * Computations done with constants at compile time can trigger these
- * even when compiling with IEEE enabled.
- */
-# pragma message disable (UNDERFLOW, FLOATOVERFL)
-
-# if (__CRTL_VER < 80000000)
-/*
- * Although the compiler supports C99 language constructs, the C
- * run-time library does not contain all C99 functions.
- *
- * This was the case for 70300022. Update the 80000000 value when
- * it has been accurately determined what version of the library
- * supports C99.
- */
-# if defined(TRIO_COMPILER_SUPPORTS_C99)
-# undef TRIO_COMPILER_SUPPORTS_C99
-# endif
-# endif
-#endif
-
-/*
- * Not all preprocessors supports the LL token.
- */
-#if defined(TRIO_COMPILER_BCB)
-#else
-# define TRIO_COMPILER_SUPPORTS_LL
-#endif
-
-#endif /* TRIO_TRIODEF_H */
diff --git a/trionan.c b/trionan.c
deleted file mode 100644
index 8767a9f..0000000
--- a/trionan.c
+++ /dev/null
@@ -1,914 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * Functions to handle special quantities in floating-point numbers
- * (that is, NaNs and infinity). They provide the capability to detect
- * and fabricate special quantities.
- *
- * Although written to be as portable as possible, it can never be
- * guaranteed to work on all platforms, as not all hardware supports
- * special quantities.
- *
- * The approach used here (approximately) is to:
- *
- * 1. Use C99 functionality when available.
- * 2. Use IEEE 754 bit-patterns if possible.
- * 3. Use platform-specific techniques.
- *
- ************************************************************************/
-
-/*
- * TODO:
- * o Put all the magic into trio_fpclassify_and_signbit(), and use this from
- * trio_isnan() etc.
- */
-
-/*************************************************************************
- * Include files
- */
-#include "triodef.h"
-#include "trionan.h"
-
-#include
-#include
-#include
-#include
-#if defined(TRIO_PLATFORM_UNIX)
-# include
-#endif
-#if defined(TRIO_COMPILER_DECC)
-# if defined(__linux__)
-# include
-# else
-# include
-# endif
-#endif
-#include
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_nan.h"
-#endif
-/** @addtogroup SpecialQuantities
- @{
-*/
-
-/*************************************************************************
- * Definitions
- */
-
-#define TRIO_TRUE (1 == 1)
-#define TRIO_FALSE (0 == 1)
-
-/*
- * We must enable IEEE floating-point on Alpha
- */
-#if defined(__alpha) && !defined(_IEEE_FP)
-# if defined(TRIO_COMPILER_DECC)
-# if defined(TRIO_PLATFORM_VMS)
-# error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE"
-# else
-# if !defined(_CFE)
-# error "Must be compiled with option -ieee"
-# endif
-# endif
-# elif defined(TRIO_COMPILER_GCC) && (defined(__osf__) || defined(__linux__))
-# error "Must be compiled with option -mieee"
-# endif
-#endif /* __alpha && ! _IEEE_FP */
-
-/*
- * In ANSI/IEEE 754-1985 64-bits double format numbers have the
- * following properties (amongst others)
- *
- * o FLT_RADIX == 2: binary encoding
- * o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used
- * to indicate special numbers (e.g. NaN and Infinity), so the
- * maximum exponent is 10 bits wide (2^10 == 1024).
- * o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because
- * numbers are normalized the initial binary 1 is represented
- * implicitly (the so-called "hidden bit"), which leaves us with
- * the ability to represent 53 bits wide mantissa.
- */
-#if (FLT_RADIX == 2) && (DBL_MAX_EXP == 1024) && (DBL_MANT_DIG == 53)
-# define USE_IEEE_754
-#endif
-
-
-/*************************************************************************
- * Constants
- */
-
-static TRIO_CONST char rcsid[] = "@(#)$Id$";
-
-#if defined(USE_IEEE_754)
-
-/*
- * Endian-agnostic indexing macro.
- *
- * The value of internalEndianMagic, when converted into a 64-bit
- * integer, becomes 0x0706050403020100 (we could have used a 64-bit
- * integer value instead of a double, but not all platforms supports
- * that type). The value is automatically encoded with the correct
- * endianness by the compiler, which means that we can support any
- * kind of endianness. The individual bytes are then used as an index
- * for the IEEE 754 bit-patterns and masks.
- */
-#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
-
-#if (defined(__BORLANDC__) && __BORLANDC__ >= 0x0590)
-static TRIO_CONST double internalEndianMagic = 7.949928895127362e-275;
-#else
-static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
-#endif
-
-/* Mask for the exponent */
-static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
- 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Mask for the mantissa */
-static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
- 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-/* Mask for the sign bit */
-static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Bit-pattern for negative zero */
-static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Bit-pattern for infinity */
-static TRIO_CONST unsigned char ieee_754_infinity_array[] = {
- 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Bit-pattern for quiet NaN */
-static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
- 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-
-/*************************************************************************
- * Functions
- */
-
-/*
- * trio_make_double
- */
-TRIO_PRIVATE double
-trio_make_double
-TRIO_ARGS1((values),
- TRIO_CONST unsigned char *values)
-{
- TRIO_VOLATILE double result;
- int i;
-
- for (i = 0; i < (int)sizeof(double); i++) {
- ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];
- }
- return result;
-}
-
-/*
- * trio_is_special_quantity
- */
-TRIO_PRIVATE int
-trio_is_special_quantity
-TRIO_ARGS2((number, has_mantissa),
- double number,
- int *has_mantissa)
-{
- unsigned int i;
- unsigned char current;
- int is_special_quantity = TRIO_TRUE;
-
- *has_mantissa = 0;
-
- for (i = 0; i < (unsigned int)sizeof(double); i++) {
- current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];
- is_special_quantity
- &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);
- *has_mantissa |= (current & ieee_754_mantissa_mask[i]);
- }
- return is_special_quantity;
-}
-
-/*
- * trio_is_negative
- */
-TRIO_PRIVATE int
-trio_is_negative
-TRIO_ARGS1((number),
- double number)
-{
- unsigned int i;
- int is_negative = TRIO_FALSE;
-
- for (i = 0; i < (unsigned int)sizeof(double); i++) {
- is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]
- & ieee_754_sign_mask[i]);
- }
- return is_negative;
-}
-
-#endif /* USE_IEEE_754 */
-
-
-/**
- Generate negative zero.
-
- @return Floating-point representation of negative zero.
-*/
-TRIO_PUBLIC double
-trio_nzero(TRIO_NOARGS)
-{
-#if defined(USE_IEEE_754)
- return trio_make_double(ieee_754_negzero_array);
-#else
- TRIO_VOLATILE double zero = 0.0;
-
- return -zero;
-#endif
-}
-
-/**
- Generate positive infinity.
-
- @return Floating-point representation of positive infinity.
-*/
-TRIO_PUBLIC double
-trio_pinf(TRIO_NOARGS)
-{
- /* Cache the result */
- static double result = 0.0;
-
- if (result == 0.0) {
-
-#if defined(INFINITY) && defined(__STDC_IEC_559__)
- result = (double)INFINITY;
-
-#elif defined(USE_IEEE_754)
- result = trio_make_double(ieee_754_infinity_array);
-
-#else
- /*
- * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used
- * as infinity. Otherwise we have to resort to an overflow
- * operation to generate infinity.
- */
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- result = HUGE_VAL;
- if (HUGE_VAL == DBL_MAX) {
- /* Force overflow */
- result += HUGE_VAL;
- }
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
-#endif
- }
- return result;
-}
-
-/**
- Generate negative infinity.
-
- @return Floating-point value of negative infinity.
-*/
-TRIO_PUBLIC double
-trio_ninf(TRIO_NOARGS)
-{
- static double result = 0.0;
-
- if (result == 0.0) {
- /*
- * Negative infinity is calculated by negating positive infinity,
- * which can be done because it is legal to do calculations on
- * infinity (for example, 1 / infinity == 0).
- */
- result = -trio_pinf();
- }
- return result;
-}
-
-/**
- Generate NaN.
-
- @return Floating-point representation of NaN.
-*/
-TRIO_PUBLIC double
-trio_nan(TRIO_NOARGS)
-{
- /* Cache the result */
- static double result = 0.0;
-
- if (result == 0.0) {
-
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
- result = nan("");
-
-#elif defined(NAN) && defined(__STDC_IEC_559__)
- result = (double)NAN;
-
-#elif defined(USE_IEEE_754)
- result = trio_make_double(ieee_754_qnan_array);
-
-#else
- /*
- * There are several ways to generate NaN. The one used here is
- * to divide infinity by infinity. I would have preferred to add
- * negative infinity to positive infinity, but that yields wrong
- * result (infinity) on FreeBSD.
- *
- * This may fail if the hardware does not support NaN, or if
- * the Invalid Operation floating-point exception is unmasked.
- */
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- result = trio_pinf() / trio_pinf();
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
-#endif
- }
- return result;
-}
-
-/**
- Check for NaN.
-
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number is a NaN.
-*/
-TRIO_PUBLIC int
-trio_isnan
-TRIO_ARGS1((number),
- double number)
-{
-#if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \
- || defined(TRIO_COMPILER_SUPPORTS_UNIX95)
- /*
- * C99 defines isnan() as a macro. UNIX95 defines isnan() as a
- * function. This function was already present in XPG4, but this
- * is a bit tricky to detect with compiler defines, so we choose
- * the conservative approach and only use it for UNIX95.
- */
- return isnan(number);
-
-#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
- /*
- * Microsoft Visual C++ and Borland C++ Builder have an _isnan()
- * function.
- */
- return _isnan(number) ? TRIO_TRUE : TRIO_FALSE;
-
-#elif defined(USE_IEEE_754)
- /*
- * Examine IEEE 754 bit-pattern. A NaN must have a special exponent
- * pattern, and a non-empty mantissa.
- */
- int has_mantissa;
- int is_special_quantity;
-
- is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
-
- return (is_special_quantity && has_mantissa);
-
-#else
- /*
- * Fallback solution
- */
- int status;
- double integral, fraction;
-
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- status = (/*
- * NaN is the only number which does not compare to itself
- */
- ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||
- /*
- * Fallback solution if NaN compares to NaN
- */
- ((number != 0.0) &&
- (fraction = modf(number, &integral),
- integral == fraction)));
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
- return status;
-
-#endif
-}
-
-/**
- Check for infinity.
-
- @param number An arbitrary floating-point number.
- @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
-*/
-TRIO_PUBLIC int
-trio_isinf
-TRIO_ARGS1((number),
- double number)
-{
-#if defined(TRIO_COMPILER_DECC) && !defined(__linux__)
- /*
- * DECC has an isinf() macro, but it works differently than that
- * of C99, so we use the fp_class() function instead.
- */
- return ((fp_class(number) == FP_POS_INF)
- ? 1
- : ((fp_class(number) == FP_NEG_INF) ? -1 : 0));
-
-#elif defined(isinf)
- /*
- * C99 defines isinf() as a macro.
- */
- return isinf(number)
- ? ((number > 0.0) ? 1 : -1)
- : 0;
-
-#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
- /*
- * Microsoft Visual C++ and Borland C++ Builder have an _fpclass()
- * function that can be used to detect infinity.
- */
- return ((_fpclass(number) == _FPCLASS_PINF)
- ? 1
- : ((_fpclass(number) == _FPCLASS_NINF) ? -1 : 0));
-
-#elif defined(USE_IEEE_754)
- /*
- * Examine IEEE 754 bit-pattern. Infinity must have a special exponent
- * pattern, and an empty mantissa.
- */
- int has_mantissa;
- int is_special_quantity;
-
- is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
-
- return (is_special_quantity && !has_mantissa)
- ? ((number < 0.0) ? -1 : 1)
- : 0;
-
-#else
- /*
- * Fallback solution.
- */
- int status;
-
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- double infinity = trio_pinf();
-
- status = ((number == infinity)
- ? 1
- : ((number == -infinity) ? -1 : 0));
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
- return status;
-
-#endif
-}
-
-#if 0
- /* Temporary fix - this routine is not used anywhere */
-/**
- Check for finity.
-
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number is a finite.
-*/
-TRIO_PUBLIC int
-trio_isfinite
-TRIO_ARGS1((number),
- double number)
-{
-#if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite)
- /*
- * C99 defines isfinite() as a macro.
- */
- return isfinite(number);
-
-#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
- /*
- * Microsoft Visual C++ and Borland C++ Builder use _finite().
- */
- return _finite(number);
-
-#elif defined(USE_IEEE_754)
- /*
- * Examine IEEE 754 bit-pattern. For finity we do not care about the
- * mantissa.
- */
- int dummy;
-
- return (! trio_is_special_quantity(number, &dummy));
-
-#else
- /*
- * Fallback solution.
- */
- return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0));
-
-#endif
-}
-
-#endif
-
-/*
- * The sign of NaN is always false
- */
-TRIO_PUBLIC int
-trio_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
- double number,
- int *is_negative)
-{
-#if defined(fpclassify) && defined(signbit)
- /*
- * C99 defines fpclassify() and signbit() as a macros
- */
- *is_negative = signbit(number);
- switch (fpclassify(number)) {
- case FP_NAN:
- return TRIO_FP_NAN;
- case FP_INFINITE:
- return TRIO_FP_INFINITE;
- case FP_SUBNORMAL:
- return TRIO_FP_SUBNORMAL;
- case FP_ZERO:
- return TRIO_FP_ZERO;
- default:
- return TRIO_FP_NORMAL;
- }
-
-#else
-# if defined(TRIO_COMPILER_DECC)
- /*
- * DECC has an fp_class() function.
- */
-# define TRIO_FPCLASSIFY(n) fp_class(n)
-# define TRIO_QUIET_NAN FP_QNAN
-# define TRIO_SIGNALLING_NAN FP_SNAN
-# define TRIO_POSITIVE_INFINITY FP_POS_INF
-# define TRIO_NEGATIVE_INFINITY FP_NEG_INF
-# define TRIO_POSITIVE_SUBNORMAL FP_POS_DENORM
-# define TRIO_NEGATIVE_SUBNORMAL FP_NEG_DENORM
-# define TRIO_POSITIVE_ZERO FP_POS_ZERO
-# define TRIO_NEGATIVE_ZERO FP_NEG_ZERO
-# define TRIO_POSITIVE_NORMAL FP_POS_NORM
-# define TRIO_NEGATIVE_NORMAL FP_NEG_NORM
-
-# elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
- /*
- * Microsoft Visual C++ and Borland C++ Builder have an _fpclass()
- * function.
- */
-# define TRIO_FPCLASSIFY(n) _fpclass(n)
-# define TRIO_QUIET_NAN _FPCLASS_QNAN
-# define TRIO_SIGNALLING_NAN _FPCLASS_SNAN
-# define TRIO_POSITIVE_INFINITY _FPCLASS_PINF
-# define TRIO_NEGATIVE_INFINITY _FPCLASS_NINF
-# define TRIO_POSITIVE_SUBNORMAL _FPCLASS_PD
-# define TRIO_NEGATIVE_SUBNORMAL _FPCLASS_ND
-# define TRIO_POSITIVE_ZERO _FPCLASS_PZ
-# define TRIO_NEGATIVE_ZERO _FPCLASS_NZ
-# define TRIO_POSITIVE_NORMAL _FPCLASS_PN
-# define TRIO_NEGATIVE_NORMAL _FPCLASS_NN
-
-# elif defined(FP_PLUS_NORM)
- /*
- * HP-UX 9.x and 10.x have an fpclassify() function, that is different
- * from the C99 fpclassify() macro supported on HP-UX 11.x.
- *
- * AIX has class() for C, and _class() for C++, which returns the
- * same values as the HP-UX fpclassify() function.
- */
-# if defined(TRIO_PLATFORM_AIX)
-# if defined(__cplusplus)
-# define TRIO_FPCLASSIFY(n) _class(n)
-# else
-# define TRIO_FPCLASSIFY(n) class(n)
-# endif
-# else
-# define TRIO_FPCLASSIFY(n) fpclassify(n)
-# endif
-# define TRIO_QUIET_NAN FP_QNAN
-# define TRIO_SIGNALLING_NAN FP_SNAN
-# define TRIO_POSITIVE_INFINITY FP_PLUS_INF
-# define TRIO_NEGATIVE_INFINITY FP_MINUS_INF
-# define TRIO_POSITIVE_SUBNORMAL FP_PLUS_DENORM
-# define TRIO_NEGATIVE_SUBNORMAL FP_MINUS_DENORM
-# define TRIO_POSITIVE_ZERO FP_PLUS_ZERO
-# define TRIO_NEGATIVE_ZERO FP_MINUS_ZERO
-# define TRIO_POSITIVE_NORMAL FP_PLUS_NORM
-# define TRIO_NEGATIVE_NORMAL FP_MINUS_NORM
-# endif
-
-# if defined(TRIO_FPCLASSIFY)
- switch (TRIO_FPCLASSIFY(number)) {
- case TRIO_QUIET_NAN:
- case TRIO_SIGNALLING_NAN:
- *is_negative = TRIO_FALSE; /* NaN has no sign */
- return TRIO_FP_NAN;
- case TRIO_POSITIVE_INFINITY:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_INFINITE;
- case TRIO_NEGATIVE_INFINITY:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_INFINITE;
- case TRIO_POSITIVE_SUBNORMAL:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- case TRIO_NEGATIVE_SUBNORMAL:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- case TRIO_POSITIVE_ZERO:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_ZERO;
- case TRIO_NEGATIVE_ZERO:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_ZERO;
- case TRIO_POSITIVE_NORMAL:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NORMAL;
- case TRIO_NEGATIVE_NORMAL:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_NORMAL;
- default:
- /* Just in case... */
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
- }
-
-# else
- /*
- * Fallback solution.
- */
- int rc;
-
- if (number == 0.0) {
- /*
- * In IEEE 754 the sign of zero is ignored in comparisons, so we
- * have to handle this as a special case by examining the sign bit
- * directly.
- */
-# if defined(USE_IEEE_754)
- *is_negative = trio_is_negative(number);
-# else
- *is_negative = TRIO_FALSE; /* FIXME */
-# endif
- return TRIO_FP_ZERO;
- }
- if (trio_isnan(number)) {
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NAN;
- }
- if ((rc = trio_isinf(number))) {
- *is_negative = (rc == -1);
- return TRIO_FP_INFINITE;
- }
- if ((number > 0.0) && (number < DBL_MIN)) {
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- }
- if ((number < 0.0) && (number > -DBL_MIN)) {
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- }
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
-
-# endif
-#endif
-}
-
-/**
- Examine the sign of a number.
-
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number has the
- sign bit set (i.e. is negative).
-*/
-TRIO_PUBLIC int
-trio_signbit
-TRIO_ARGS1((number),
- double number)
-{
- int is_negative;
-
- (void)trio_fpclassify_and_signbit(number, &is_negative);
- return is_negative;
-}
-
-#if 0
- /* Temporary fix - this routine is not used in libxml */
-/**
- Examine the class of a number.
-
- @param number An arbitrary floating-point number.
- @return Enumerable value indicating the class of @p number
-*/
-TRIO_PUBLIC int
-trio_fpclassify
-TRIO_ARGS1((number),
- double number)
-{
- int dummy;
-
- return trio_fpclassify_and_signbit(number, &dummy);
-}
-
-#endif
-
-/** @} SpecialQuantities */
-
-/*************************************************************************
- * For test purposes.
- *
- * Add the following compiler option to include this test code.
- *
- * Unix : -DSTANDALONE
- * VMS : /DEFINE=(STANDALONE)
- */
-#if defined(STANDALONE)
-# include
-
-static TRIO_CONST char *
-getClassification
-TRIO_ARGS1((type),
- int type)
-{
- switch (type) {
- case TRIO_FP_INFINITE:
- return "FP_INFINITE";
- case TRIO_FP_NAN:
- return "FP_NAN";
- case TRIO_FP_NORMAL:
- return "FP_NORMAL";
- case TRIO_FP_SUBNORMAL:
- return "FP_SUBNORMAL";
- case TRIO_FP_ZERO:
- return "FP_ZERO";
- default:
- return "FP_UNKNOWN";
- }
-}
-
-static void
-print_class
-TRIO_ARGS2((prefix, number),
- TRIO_CONST char *prefix,
- double number)
-{
- printf("%-6s: %s %-15s %g\n",
- prefix,
- trio_signbit(number) ? "-" : "+",
- getClassification(TRIO_FPCLASSIFY(number)),
- number);
-}
-
-int main(TRIO_NOARGS)
-{
- double my_nan;
- double my_pinf;
- double my_ninf;
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler) TRIO_PROTO((int));
-# endif
-
- my_nan = trio_nan();
- my_pinf = trio_pinf();
- my_ninf = trio_ninf();
-
- print_class("Nan", my_nan);
- print_class("PInf", my_pinf);
- print_class("NInf", my_ninf);
- print_class("PZero", 0.0);
- print_class("NZero", -0.0);
- print_class("PNorm", 1.0);
- print_class("NNorm", -1.0);
- print_class("PSub", 1.01e-307 - 1.00e-307);
- print_class("NSub", 1.00e-307 - 1.01e-307);
-
- printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_nan,
- ((unsigned char *)&my_nan)[0],
- ((unsigned char *)&my_nan)[1],
- ((unsigned char *)&my_nan)[2],
- ((unsigned char *)&my_nan)[3],
- ((unsigned char *)&my_nan)[4],
- ((unsigned char *)&my_nan)[5],
- ((unsigned char *)&my_nan)[6],
- ((unsigned char *)&my_nan)[7],
- trio_isnan(my_nan), trio_isinf(my_nan));
- printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_pinf,
- ((unsigned char *)&my_pinf)[0],
- ((unsigned char *)&my_pinf)[1],
- ((unsigned char *)&my_pinf)[2],
- ((unsigned char *)&my_pinf)[3],
- ((unsigned char *)&my_pinf)[4],
- ((unsigned char *)&my_pinf)[5],
- ((unsigned char *)&my_pinf)[6],
- ((unsigned char *)&my_pinf)[7],
- trio_isnan(my_pinf), trio_isinf(my_pinf));
- printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_ninf,
- ((unsigned char *)&my_ninf)[0],
- ((unsigned char *)&my_ninf)[1],
- ((unsigned char *)&my_ninf)[2],
- ((unsigned char *)&my_ninf)[3],
- ((unsigned char *)&my_ninf)[4],
- ((unsigned char *)&my_ninf)[5],
- ((unsigned char *)&my_ninf)[6],
- ((unsigned char *)&my_ninf)[7],
- trio_isnan(my_ninf), trio_isinf(my_ninf));
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal_handler = signal(SIGFPE, SIG_IGN);
-# endif
-
- my_pinf = DBL_MAX + DBL_MAX;
- my_ninf = -my_pinf;
- my_nan = my_pinf / my_pinf;
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
- printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_nan,
- ((unsigned char *)&my_nan)[0],
- ((unsigned char *)&my_nan)[1],
- ((unsigned char *)&my_nan)[2],
- ((unsigned char *)&my_nan)[3],
- ((unsigned char *)&my_nan)[4],
- ((unsigned char *)&my_nan)[5],
- ((unsigned char *)&my_nan)[6],
- ((unsigned char *)&my_nan)[7],
- trio_isnan(my_nan), trio_isinf(my_nan));
- printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_pinf,
- ((unsigned char *)&my_pinf)[0],
- ((unsigned char *)&my_pinf)[1],
- ((unsigned char *)&my_pinf)[2],
- ((unsigned char *)&my_pinf)[3],
- ((unsigned char *)&my_pinf)[4],
- ((unsigned char *)&my_pinf)[5],
- ((unsigned char *)&my_pinf)[6],
- ((unsigned char *)&my_pinf)[7],
- trio_isnan(my_pinf), trio_isinf(my_pinf));
- printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_ninf,
- ((unsigned char *)&my_ninf)[0],
- ((unsigned char *)&my_ninf)[1],
- ((unsigned char *)&my_ninf)[2],
- ((unsigned char *)&my_ninf)[3],
- ((unsigned char *)&my_ninf)[4],
- ((unsigned char *)&my_ninf)[5],
- ((unsigned char *)&my_ninf)[6],
- ((unsigned char *)&my_ninf)[7],
- trio_isnan(my_ninf), trio_isinf(my_ninf));
-
- return 0;
-}
-#endif
diff --git a/trionan.h b/trionan.h
deleted file mode 100644
index eac0e6f..0000000
--- a/trionan.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_NAN_H
-#define TRIO_NAN_H
-
-#include "triodef.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
- TRIO_FP_INFINITE,
- TRIO_FP_NAN,
- TRIO_FP_NORMAL,
- TRIO_FP_SUBNORMAL,
- TRIO_FP_ZERO
-};
-
-/*
- * Return NaN (Not-a-Number).
- */
-TRIO_PUBLIC double trio_nan TRIO_PROTO((void));
-
-/*
- * Return positive infinity.
- */
-TRIO_PUBLIC double trio_pinf TRIO_PROTO((void));
-
-/*
- * Return negative infinity.
- */
-TRIO_PUBLIC double trio_ninf TRIO_PROTO((void));
-
-/*
- * Return negative zero.
- */
-TRIO_PUBLIC double trio_nzero TRIO_PROTO((TRIO_NOARGS));
-
-/*
- * If number is a NaN return non-zero, otherwise return zero.
- */
-TRIO_PUBLIC int trio_isnan TRIO_PROTO((double number));
-
-/*
- * If number is positive infinity return 1, if number is negative
- * infinity return -1, otherwise return 0.
- */
-TRIO_PUBLIC int trio_isinf TRIO_PROTO((double number));
-
-/*
- * If number is finite return non-zero, otherwise return zero.
- */
-#if 0
- /* Temporary fix - these 2 routines not used in libxml */
-TRIO_PUBLIC int trio_isfinite TRIO_PROTO((double number));
-
-TRIO_PUBLIC int trio_fpclassify TRIO_PROTO((double number));
-#endif
-
-TRIO_PUBLIC int trio_signbit TRIO_PROTO((double number));
-
-TRIO_PUBLIC int trio_fpclassify_and_signbit TRIO_PROTO((double number, int *is_negative));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRIO_NAN_H */
diff --git a/triop.h b/triop.h
deleted file mode 100644
index 6d486f8..0000000
--- a/triop.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * Private functions, types, etc. used for callback functions.
- *
- * The ref pointer is an opaque type and should remain as such.
- * Private data must only be accessible through the getter and
- * setter functions.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIOP_H
-#define TRIO_TRIOP_H
-
-#include "triodef.h"
-
-#include
-#if defined(TRIO_COMPILER_ANCIENT)
-# include
-#else
-# include
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef TRIO_C99
-# define TRIO_C99 1
-#endif
-#ifndef TRIO_BSD
-# define TRIO_BSD 1
-#endif
-#ifndef TRIO_GNU
-# define TRIO_GNU 1
-#endif
-#ifndef TRIO_MISC
-# define TRIO_MISC 1
-#endif
-#ifndef TRIO_UNIX98
-# define TRIO_UNIX98 1
-#endif
-#ifndef TRIO_MICROSOFT
-# define TRIO_MICROSOFT 1
-#endif
-#ifndef TRIO_EXTENSION
-# define TRIO_EXTENSION 1
-#endif
-#ifndef TRIO_WIDECHAR /* Does not work yet. Do not enable */
-# define TRIO_WIDECHAR 0
-#endif
-#ifndef TRIO_ERRORS
-# define TRIO_ERRORS 1
-#endif
-
-#ifndef TRIO_MALLOC
-# define TRIO_MALLOC(n) malloc(n)
-#endif
-#ifndef TRIO_REALLOC
-# define TRIO_REALLOC(x,n) realloc((x),(n))
-#endif
-#ifndef TRIO_FREE
-# define TRIO_FREE(x) free(x)
-#endif
-
-
-/*************************************************************************
- * User-defined specifiers
- */
-
-typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t));
-
-trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name));
-void trio_unregister TRIO_PROTO((trio_pointer_t handle));
-
-TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref));
-trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref));
-
-/* Modifiers */
-int trio_get_width TRIO_PROTO((trio_pointer_t ref));
-void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width));
-int trio_get_precision TRIO_PROTO((trio_pointer_t ref));
-void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision));
-int trio_get_base TRIO_PROTO((trio_pointer_t ref));
-void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base));
-int trio_get_padding TRIO_PROTO((trio_pointer_t ref));
-void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding));
-int trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */
-void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort));
-int trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */
-void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short));
-int trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */
-void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long));
-int trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */
-void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong));
-int trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */
-void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble));
-int trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */
-void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative));
-int trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */
-void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned));
-int trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* TRIO_PROTO((space) */
-void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space));
-int trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */
-void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign));
-int trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */
-void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote));
-int trio_get_upper TRIO_PROTO((trio_pointer_t ref));
-void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper));
-#if TRIO_C99
-int trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */
-void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest));
-int trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */
-void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff));
-int trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */
-void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size));
-#endif
-
-/* Printing */
-int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...));
-int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args));
-int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args));
-
-void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number));
-void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number));
-/* void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */
-/* void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */
-void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number));
-void trio_print_string TRIO_PROTO((trio_pointer_t ref, char *string));
-void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer));
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* TRIO_TRIOP_H */
diff --git a/triostr.c b/triostr.c
deleted file mode 100644
index 5937a44..0000000
--- a/triostr.c
+++ /dev/null
@@ -1,2112 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/*************************************************************************
- * Include files
- */
-
-#include
-#include
-#include
-#include
-#include
-#include "triodef.h"
-#include "triostr.h"
-
-/*************************************************************************
- * Definitions
- */
-
-#if !defined(TRIO_STRING_PUBLIC)
-# define TRIO_STRING_PUBLIC TRIO_PUBLIC
-#endif
-#if !defined(TRIO_STRING_PRIVATE)
-# define TRIO_STRING_PRIVATE TRIO_PRIVATE
-#endif
-
-#if !defined(NULL)
-# define NULL 0
-#endif
-#if !defined(NIL)
-# define NIL ((char)0)
-#endif
-#if !defined(FALSE)
-# define FALSE (1 == 0)
-# define TRUE (! FALSE)
-#endif
-#if !defined(BOOLEAN_T)
-# define BOOLEAN_T int
-#endif
-
-#ifdef __VMS
-# define USE_STRTOD
-#elif defined(TRIO_COMPILER_SUPPORTS_C99)
-# define USE_STRTOD
-# define USE_STRTOF
-#elif defined(TRIO_COMPILER_MSVC)
-# define USE_STRTOD
-#endif
-
-#if defined(TRIO_PLATFORM_UNIX)
-# define USE_STRCASECMP
-# define USE_STRNCASECMP
-# if defined(TRIO_PLATFORM_SUNOS)
-# define USE_SYS_ERRLIST
-# else
-# define USE_STRERROR
-# endif
-# if defined(TRIO_PLATFORM_QNX)
-# define strcasecmp(x,y) stricmp(x,y)
-# define strncasecmp(x,y,n) strnicmp(x,y,n)
-# endif
-#elif defined(TRIO_PLATFORM_WIN32)
-# define USE_STRCASECMP
-# if defined(_WIN32_WCE)
-# define strcasecmp(x,y) _stricmp(x,y)
-# else
-# define strcasecmp(x,y) strcmpi(x,y)
-# endif
-#elif defined(TRIO_PLATFORM_OS400)
-# define USE_STRCASECMP
-# define USE_STRNCASECMP
-# include
-#endif
-
-#if !(defined(TRIO_PLATFORM_SUNOS))
-# define USE_TOLOWER
-# define USE_TOUPPER
-#endif
-
-/*************************************************************************
- * Structures
- */
-
-struct _trio_string_t
-{
- char *content;
- size_t length;
- size_t allocated;
-};
-
-/*************************************************************************
- * Constants
- */
-
-#if !defined(TRIO_MINIMAL)
-static TRIO_CONST char rcsid[] = "@(#)$Id$";
-#endif
-
-/*************************************************************************
- * Static String Functions
- */
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_static.h"
-#endif
-/** @addtogroup StaticStrings
- @{
-*/
-
-/**
- Create new string.
-
- @param size Size of new string.
- @return Pointer to string, or NULL if allocation failed.
-*/
-TRIO_STRING_PUBLIC char *
-trio_create
-TRIO_ARGS1((size),
- size_t size)
-{
- return (char *)TRIO_MALLOC(size);
-}
-
-
-/**
- Destroy string.
-
- @param string String to be freed.
-*/
-TRIO_STRING_PUBLIC void
-trio_destroy
-TRIO_ARGS1((string),
- char *string)
-{
- if (string)
- {
- TRIO_FREE(string);
- }
-}
-
-
-/**
- Count the number of characters in a string.
-
- @param string String to measure.
- @return Number of characters in @string.
-*/
-TRIO_STRING_PUBLIC size_t
-trio_length
-TRIO_ARGS1((string),
- TRIO_CONST char *string)
-{
- return strlen(string);
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Append @p source at the end of @p target.
-
- @param target Target string.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chunk with sufficient room to
- contain the @p target string and @p source string.
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC int
-trio_append
-TRIO_ARGS2((target, source),
- char *target,
- TRIO_CONST char *source)
-{
- assert(target);
- assert(source);
-
- return (strcat(target, source) != NULL);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-#if !defined(TRIO_MINIMAL)
-/**
- Append at most @p max characters from @p source to @p target.
-
- @param target Target string.
- @param max Maximum number of characters to append.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chuck with sufficient room to
- contain the @p target string and the @p source string (at most @p max
- characters).
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC int
-trio_append_max
-TRIO_ARGS3((target, max, source),
- char *target,
- size_t max,
- TRIO_CONST char *source)
-{
- size_t length;
-
- assert(target);
- assert(source);
-
- length = trio_length(target);
-
- if (max > length)
- {
- strncat(target, source, max - length - 1);
- }
- return TRUE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Determine if a string contains a substring.
-
- @param string String to be searched.
- @param substring String to be found.
- @return Boolean value indicating success or failure.
-*/
-TRIO_STRING_PUBLIC int
-trio_contains
-TRIO_ARGS2((string, substring),
- TRIO_CONST char *string,
- TRIO_CONST char *substring)
-{
- assert(string);
- assert(substring);
-
- return (0 != strstr(string, substring));
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Copy @p source to @p target.
-
- @param target Target string.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chunk with sufficient room to
- contain the @p source string.
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC int
-trio_copy
-TRIO_ARGS2((target, source),
- char *target,
- TRIO_CONST char *source)
-{
- assert(target);
- assert(source);
-
- (void)strcpy(target, source);
- return TRUE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Copy at most @p max characters from @p source to @p target.
-
- @param target Target string.
- @param max Maximum number of characters to append.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chunk with sufficient room to
- contain the @p source string (at most @p max characters).
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC int
-trio_copy_max
-TRIO_ARGS3((target, max, source),
- char *target,
- size_t max,
- TRIO_CONST char *source)
-{
- assert(target);
- assert(source);
- assert(max > 0); /* Includes != 0 */
-
- (void)strncpy(target, source, max - 1);
- target[max - 1] = (char)0;
- return TRUE;
-}
-
-
-/*
- * TrioDuplicateMax
- */
-TRIO_STRING_PRIVATE char *
-TrioDuplicateMax
-TRIO_ARGS2((source, size),
- TRIO_CONST char *source,
- size_t size)
-{
- char *target;
-
- assert(source);
-
- /* Make room for string plus a terminating zero */
- size++;
- target = trio_create(size);
- if (target)
- {
- trio_copy_max(target, size, source);
- }
- return target;
-}
-
-
-/**
- Duplicate @p source.
-
- @param source Source string.
- @return A copy of the @p source string.
-
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC char *
-trio_duplicate
-TRIO_ARGS1((source),
- TRIO_CONST char *source)
-{
- return TrioDuplicateMax(source, trio_length(source));
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Duplicate at most @p max characters of @p source.
-
- @param source Source string.
- @param max Maximum number of characters to duplicate.
- @return A copy of the @p source string.
-
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC char *
-trio_duplicate_max TRIO_ARGS2((source, max),
- TRIO_CONST char *source,
- size_t max)
-{
- size_t length;
-
- assert(source);
- assert(max > 0);
-
- length = trio_length(source);
- if (length > max)
- {
- length = max;
- }
- return TrioDuplicateMax(source, length);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Compare if two strings are equal.
-
- @param first First string.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-insensitive comparison.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal
-TRIO_ARGS2((first, second),
- TRIO_CONST char *first,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
-#if defined(USE_STRCASECMP)
- return (0 == strcasecmp(first, second));
-#else
- while ((*first != NIL) && (*second != NIL))
- {
- if (trio_to_upper(*first) != trio_to_upper(*second))
- {
- break;
- }
- first++;
- second++;
- }
- return ((*first == NIL) && (*second == NIL));
-#endif
- }
- return FALSE;
-}
-
-
-/**
- Compare if two strings are equal.
-
- @param first First string.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-sensitive comparison.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal_case
-TRIO_ARGS2((first, second),
- TRIO_CONST char *first,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
- return (0 == strcmp(first, second));
- }
- return FALSE;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Compare if two strings up until the first @p max characters are equal.
-
- @param first First string.
- @param max Maximum number of characters to compare.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-sensitive comparison.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal_case_max
-TRIO_ARGS3((first, max, second),
- TRIO_CONST char *first,
- size_t max,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
- return (0 == strncmp(first, second, max));
- }
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Compare if two strings are equal.
-
- @param first First string.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Collating characters are considered equal.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal_locale
-TRIO_ARGS2((first, second),
- TRIO_CONST char *first,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
-#if defined(LC_COLLATE)
- return (strcoll(first, second) == 0);
-#else
- return trio_equal(first, second);
-#endif
-}
-
-
-/**
- Compare if two strings up until the first @p max characters are equal.
-
- @param first First string.
- @param max Maximum number of characters to compare.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-insensitive comparison.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal_max
-TRIO_ARGS3((first, max, second),
- TRIO_CONST char *first,
- size_t max,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
-#if defined(USE_STRNCASECMP)
- return (0 == strncasecmp(first, second, max));
-#else
- /* Not adequately tested yet */
- size_t cnt = 0;
- while ((*first != NIL) && (*second != NIL) && (cnt <= max))
- {
- if (trio_to_upper(*first) != trio_to_upper(*second))
- {
- break;
- }
- first++;
- second++;
- cnt++;
- }
- return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
-#endif
- }
- return FALSE;
-}
-
-
-/**
- Provide a textual description of an error code (errno).
-
- @param error_number Error number.
- @return Textual description of @p error_number.
-*/
-TRIO_STRING_PUBLIC TRIO_CONST char *
-trio_error
-TRIO_ARGS1((error_number),
- int error_number)
-{
-#if defined(USE_STRERROR)
-
- return strerror(error_number);
-
-#elif defined(USE_SYS_ERRLIST)
-
- extern char *sys_errlist[];
- extern int sys_nerr;
-
- return ((error_number < 0) || (error_number >= sys_nerr))
- ? "unknown"
- : sys_errlist[error_number];
-
-#else
-
- return "unknown";
-
-#endif
-}
-
-
-#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
-/**
- Format the date/time according to @p format.
-
- @param target Target string.
- @param max Maximum number of characters to format.
- @param format Formatting string.
- @param datetime Date/time structure.
- @return Number of formatted characters.
-
- The formatting string accepts the same specifiers as the standard C
- function strftime.
-*/
-TRIO_STRING_PUBLIC size_t
-trio_format_date_max
-TRIO_ARGS4((target, max, format, datetime),
- char *target,
- size_t max,
- TRIO_CONST char *format,
- TRIO_CONST struct tm *datetime)
-{
- assert(target);
- assert(format);
- assert(datetime);
- assert(max > 0);
-
- return strftime(target, max, format, datetime);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Calculate a hash value for a string.
-
- @param string String to be calculated on.
- @param type Hash function.
- @return Calculated hash value.
-
- @p type can be one of the following
- @li @c TRIO_HASH_PLAIN Plain hash function.
-*/
-TRIO_STRING_PUBLIC unsigned long
-trio_hash
-TRIO_ARGS2((string, type),
- TRIO_CONST char *string,
- int type)
-{
- unsigned long value = 0L;
- char ch;
-
- assert(string);
-
- switch (type)
- {
- case TRIO_HASH_PLAIN:
- while ( (ch = *string++) != NIL )
- {
- value *= 31;
- value += (unsigned long)ch;
- }
- break;
- default:
- assert(FALSE);
- break;
- }
- return value;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Find first occurrence of a character in a string.
-
- @param string String to be searched.
- @param character Character to be found.
- @param A pointer to the found character, or NULL if character was not found.
- */
-TRIO_STRING_PUBLIC char *
-trio_index
-TRIO_ARGS2((string, character),
- TRIO_CONST char *string,
- int character)
-{
- assert(string);
-
- return strchr(string, character);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Find last occurrence of a character in a string.
-
- @param string String to be searched.
- @param character Character to be found.
- @param A pointer to the found character, or NULL if character was not found.
- */
-TRIO_STRING_PUBLIC char *
-trio_index_last
-TRIO_ARGS2((string, character),
- TRIO_CONST char *string,
- int character)
-{
- assert(string);
-
- return strchr(string, character);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Convert the alphabetic letters in the string to lower-case.
-
- @param target String to be converted.
- @return Number of processed characters (converted or not).
-*/
-TRIO_STRING_PUBLIC int
-trio_lower
-TRIO_ARGS1((target),
- char *target)
-{
- assert(target);
-
- return trio_span_function(target, target, trio_to_lower);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Compare two strings using wildcards.
-
- @param string String to be searched.
- @param pattern Pattern, including wildcards, to search for.
- @return Boolean value indicating success or failure.
-
- Case-insensitive comparison.
-
- The following wildcards can be used
- @li @c * Match any number of characters.
- @li @c ? Match a single character.
-*/
-TRIO_STRING_PUBLIC int
-trio_match
-TRIO_ARGS2((string, pattern),
- TRIO_CONST char *string,
- TRIO_CONST char *pattern)
-{
- assert(string);
- assert(pattern);
-
- for (; ('*' != *pattern); ++pattern, ++string)
- {
- if (NIL == *string)
- {
- return (NIL == *pattern);
- }
- if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
- && ('?' != *pattern))
- {
- return FALSE;
- }
- }
- /* two-line patch to prevent *too* much recursiveness: */
- while ('*' == pattern[1])
- pattern++;
-
- do
- {
- if ( trio_match(string, &pattern[1]) )
- {
- return TRUE;
- }
- }
- while (*string++);
-
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Compare two strings using wildcards.
-
- @param string String to be searched.
- @param pattern Pattern, including wildcards, to search for.
- @return Boolean value indicating success or failure.
-
- Case-sensitive comparison.
-
- The following wildcards can be used
- @li @c * Match any number of characters.
- @li @c ? Match a single character.
-*/
-TRIO_STRING_PUBLIC int
-trio_match_case
-TRIO_ARGS2((string, pattern),
- TRIO_CONST char *string,
- TRIO_CONST char *pattern)
-{
- assert(string);
- assert(pattern);
-
- for (; ('*' != *pattern); ++pattern, ++string)
- {
- if (NIL == *string)
- {
- return (NIL == *pattern);
- }
- if ((*string != *pattern)
- && ('?' != *pattern))
- {
- return FALSE;
- }
- }
- /* two-line patch to prevent *too* much recursiveness: */
- while ('*' == pattern[1])
- pattern++;
-
- do
- {
- if ( trio_match_case(string, &pattern[1]) )
- {
- return TRUE;
- }
- }
- while (*string++);
-
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Execute a function on each character in string.
-
- @param target Target string.
- @param source Source string.
- @param Function Function to be executed.
- @return Number of processed characters.
-*/
-TRIO_STRING_PUBLIC size_t
-trio_span_function
-TRIO_ARGS3((target, source, Function),
- char *target,
- TRIO_CONST char *source,
- int (*Function) TRIO_PROTO((int)))
-{
- size_t count = 0;
-
- assert(target);
- assert(source);
- assert(Function);
-
- while (*source != NIL)
- {
- *target++ = Function(*source++);
- count++;
- }
- return count;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Search for a substring in a string.
-
- @param string String to be searched.
- @param substring String to be found.
- @return Pointer to first occurrence of @p substring in @p string, or NULL
- if no match was found.
-*/
-TRIO_STRING_PUBLIC char *
-trio_substring
-TRIO_ARGS2((string, substring),
- TRIO_CONST char *string,
- TRIO_CONST char *substring)
-{
- assert(string);
- assert(substring);
-
- return strstr(string, substring);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Search for a substring in the first @p max characters of a string.
-
- @param string String to be searched.
- @param max Maximum characters to be searched.
- @param substring String to be found.
- @return Pointer to first occurrence of @p substring in @p string, or NULL
- if no match was found.
-*/
-TRIO_STRING_PUBLIC char *
-trio_substring_max
-TRIO_ARGS3((string, max, substring),
- TRIO_CONST char *string,
- size_t max,
- TRIO_CONST char *substring)
-{
- size_t count;
- size_t size;
- char *result = NULL;
-
- assert(string);
- assert(substring);
-
- size = trio_length(substring);
- if (size <= max)
- {
- for (count = 0; count <= max - size; count++)
- {
- if (trio_equal_max(substring, size, &string[count]))
- {
- result = (char *)&string[count];
- break;
- }
- }
- }
- return result;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Tokenize string.
-
- @param string String to be tokenized.
- @param tokens String containing list of delimiting characters.
- @return Start of new token.
-
- @warning @p string will be destroyed.
-*/
-TRIO_STRING_PUBLIC char *
-trio_tokenize
-TRIO_ARGS2((string, delimiters),
- char *string,
- TRIO_CONST char *delimiters)
-{
- assert(delimiters);
-
- return strtok(string, delimiters);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Convert string to floating-point number.
-
- @param source String to be converted.
- @param endp Pointer to end of the converted string.
- @return A floating-point number.
-
- The following Extended Backus-Naur form is used
- @verbatim
- double ::= [ ]
- ( |
- |
- )
- [ [ ] ]
- number ::= 1*( )
- digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
- exponential ::= ( 'e' | 'E' )
- sign ::= ( '-' | '+' )
- decimal_point ::= '.'
- @endverbatim
-*/
-/* FIXME: Add EBNF for hex-floats */
-TRIO_STRING_PUBLIC trio_long_double_t
-trio_to_long_double
-TRIO_ARGS2((source, endp),
- TRIO_CONST char *source,
- char **endp)
-{
-#if defined(USE_STRTOLD)
- return strtold(source, endp);
-#else
- int isNegative = FALSE;
- int isExponentNegative = FALSE;
- trio_long_double_t integer = 0.0;
- trio_long_double_t fraction = 0.0;
- unsigned long exponent = 0;
- trio_long_double_t base;
- trio_long_double_t fracdiv = 1.0;
- trio_long_double_t value = 0.0;
-
- /* First try hex-floats */
- if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
- {
- base = 16.0;
- source += 2;
- while (isxdigit((int)*source))
- {
- integer *= base;
- integer += (isdigit((int)*source)
- ? (*source - '0')
- : 10 + (trio_to_upper((int)*source) - 'A'));
- source++;
- }
- if (*source == '.')
- {
- source++;
- while (isxdigit((int)*source))
- {
- fracdiv /= base;
- fraction += fracdiv * (isdigit((int)*source)
- ? (*source - '0')
- : 10 + (trio_to_upper((int)*source) - 'A'));
- source++;
- }
- if ((*source == 'p') || (*source == 'P'))
- {
- source++;
- if ((*source == '+') || (*source == '-'))
- {
- isExponentNegative = (*source == '-');
- source++;
- }
- while (isdigit((int)*source))
- {
- exponent *= 10;
- exponent += (*source - '0');
- source++;
- }
- }
- }
- /* For later use with exponent */
- base = 2.0;
- }
- else /* Then try normal decimal floats */
- {
- base = 10.0;
- isNegative = (*source == '-');
- /* Skip sign */
- if ((*source == '+') || (*source == '-'))
- source++;
-
- /* Integer part */
- while (isdigit((int)*source))
- {
- integer *= base;
- integer += (*source - '0');
- source++;
- }
-
- if (*source == '.')
- {
- source++; /* skip decimal point */
- while (isdigit((int)*source))
- {
- fracdiv /= base;
- fraction += (*source - '0') * fracdiv;
- source++;
- }
- }
- if ((*source == 'e')
- || (*source == 'E')
-#if TRIO_MICROSOFT
- || (*source == 'd')
- || (*source == 'D')
-#endif
- )
- {
- source++; /* Skip exponential indicator */
- isExponentNegative = (*source == '-');
- if ((*source == '+') || (*source == '-'))
- source++;
- while (isdigit((int)*source))
- {
- exponent *= (int)base;
- exponent += (*source - '0');
- source++;
- }
- }
- }
-
- value = integer + fraction;
- if (exponent != 0)
- {
- if (isExponentNegative)
- value /= pow(base, (double)exponent);
- else
- value *= pow(base, (double)exponent);
- }
- if (isNegative)
- value = -value;
-
- if (endp)
- *endp = (char *)source;
- return value;
-#endif
-}
-
-
-/**
- Convert string to floating-point number.
-
- @param source String to be converted.
- @param endp Pointer to end of the converted string.
- @return A floating-point number.
-
- See @ref trio_to_long_double.
-*/
-TRIO_STRING_PUBLIC double
-trio_to_double
-TRIO_ARGS2((source, endp),
- TRIO_CONST char *source,
- char **endp)
-{
-#if defined(USE_STRTOD)
- return strtod(source, endp);
-#else
- return (double)trio_to_long_double(source, endp);
-#endif
-}
-
-#if !defined(TRIO_MINIMAL)
-/**
- Convert string to floating-point number.
-
- @param source String to be converted.
- @param endp Pointer to end of the converted string.
- @return A floating-point number.
-
- See @ref trio_to_long_double.
-*/
-TRIO_STRING_PUBLIC float
-trio_to_float
-TRIO_ARGS2((source, endp),
- TRIO_CONST char *source,
- char **endp)
-{
-#if defined(USE_STRTOF)
- return strtof(source, endp);
-#else
- return (float)trio_to_long_double(source, endp);
-#endif
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Convert string to signed integer.
-
- @param string String to be converted.
- @param endp Pointer to end of converted string.
- @param base Radix number of number.
-*/
-TRIO_STRING_PUBLIC long
-trio_to_long
-TRIO_ARGS3((string, endp, base),
- TRIO_CONST char *string,
- char **endp,
- int base)
-{
- assert(string);
- assert((base >= 2) && (base <= 36));
-
- return strtol(string, endp, base);
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Convert one alphabetic letter to lower-case.
-
- @param source The letter to be converted.
- @return The converted letter.
-*/
-TRIO_STRING_PUBLIC int
-trio_to_lower
-TRIO_ARGS1((source),
- int source)
-{
-#if defined(USE_TOLOWER)
-
- return tolower(source);
-
-#else
-
- /* Does not handle locales or non-contiguous alphabetic characters */
- return ((source >= (int)'A') && (source <= (int)'Z'))
- ? source - 'A' + 'a'
- : source;
-
-#endif
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-#if !defined(TRIO_MINIMAL)
-/**
- Convert string to unsigned integer.
-
- @param string String to be converted.
- @param endp Pointer to end of converted string.
- @param base Radix number of number.
-*/
-TRIO_STRING_PUBLIC unsigned long
-trio_to_unsigned_long
-TRIO_ARGS3((string, endp, base),
- TRIO_CONST char *string,
- char **endp,
- int base)
-{
- assert(string);
- assert((base >= 2) && (base <= 36));
-
- return strtoul(string, endp, base);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Convert one alphabetic letter to upper-case.
-
- @param source The letter to be converted.
- @return The converted letter.
-*/
-TRIO_STRING_PUBLIC int
-trio_to_upper
-TRIO_ARGS1((source),
- int source)
-{
-#if defined(USE_TOUPPER)
-
- return toupper(source);
-
-#else
-
- /* Does not handle locales or non-contiguous alphabetic characters */
- return ((source >= (int)'a') && (source <= (int)'z'))
- ? source - 'a' + 'A'
- : source;
-
-#endif
-}
-
-#if !defined(TRIO_MINIMAL)
-/**
- Convert the alphabetic letters in the string to upper-case.
-
- @param target The string to be converted.
- @return The number of processed characters (converted or not).
-*/
-TRIO_STRING_PUBLIC int
-trio_upper
-TRIO_ARGS1((target),
- char *target)
-{
- assert(target);
-
- return trio_span_function(target, target, trio_to_upper);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/** @} End of StaticStrings */
-
-
-/*************************************************************************
- * Dynamic String Functions
- */
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_dynamic.h"
-#endif
-/** @addtogroup DynamicStrings
- @{
-*/
-
-/*
- * TrioStringAlloc
- */
-TRIO_STRING_PRIVATE trio_string_t *
-TrioStringAlloc(TRIO_NOARGS)
-{
- trio_string_t *self;
-
- self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
- if (self)
- {
- self->content = NULL;
- self->length = 0;
- self->allocated = 0;
- }
- return self;
-}
-
-
-/*
- * TrioStringGrow
- *
- * The size of the string will be increased by 'delta' characters. If
- * 'delta' is zero, the size will be doubled.
- */
-TRIO_STRING_PRIVATE BOOLEAN_T
-TrioStringGrow
-TRIO_ARGS2((self, delta),
- trio_string_t *self,
- size_t delta)
-{
- BOOLEAN_T status = FALSE;
- char *new_content;
- size_t new_size;
-
- new_size = (delta == 0)
- ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
- : self->allocated + delta;
-
- new_content = (char *)TRIO_REALLOC(self->content, new_size);
- if (new_content)
- {
- self->content = new_content;
- self->allocated = new_size;
- status = TRUE;
- }
- return status;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * TrioStringGrowTo
- *
- * The size of the string will be increased to 'length' plus one characters.
- * If 'length' is less than the original size, the original size will be
- * used (that is, the size of the string is never decreased).
- */
-TRIO_STRING_PRIVATE BOOLEAN_T
-TrioStringGrowTo
-TRIO_ARGS2((self, length),
- trio_string_t *self,
- size_t length)
-{
- length++; /* Room for terminating zero */
- return (self->allocated < length)
- ? TrioStringGrow(self, length - self->allocated)
- : TRUE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Create a new dynamic string.
-
- @param initial_size Initial size of the buffer.
- @return Newly allocated dynamic string, or NULL if memory allocation failed.
-*/
-TRIO_STRING_PUBLIC trio_string_t *
-trio_string_create
-TRIO_ARGS1((initial_size),
- int initial_size)
-{
- trio_string_t *self;
-
- self = TrioStringAlloc();
- if (self)
- {
- if (TrioStringGrow(self,
- (size_t)((initial_size > 0) ? initial_size : 1)))
- {
- self->content[0] = (char)0;
- self->allocated = initial_size;
- }
- else
- {
- trio_string_destroy(self);
- self = NULL;
- }
- }
- return self;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Deallocate the dynamic string and its contents.
-
- @param self Dynamic string
-*/
-TRIO_STRING_PUBLIC void
-trio_string_destroy
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- if (self)
- {
- trio_destroy(self->content);
- TRIO_FREE(self);
- }
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Get a pointer to the content.
-
- @param self Dynamic string.
- @param offset Offset into content.
- @return Pointer to the content.
-
- @p Offset can be zero, positive, or negative. If @p offset is zero,
- then the start of the content will be returned. If @p offset is positive,
- then a pointer to @p offset number of characters from the beginning of the
- content is returned. If @p offset is negative, then a pointer to @p offset
- number of characters from the ending of the string, starting at the
- terminating zero, is returned.
-*/
-TRIO_STRING_PUBLIC char *
-trio_string_get
-TRIO_ARGS2((self, offset),
- trio_string_t *self,
- int offset)
-{
- char *result = NULL;
-
- assert(self);
-
- if (self->content != NULL)
- {
- if (self->length == 0)
- {
- (void)trio_string_length(self);
- }
- if (offset >= 0)
- {
- if (offset > (int)self->length)
- {
- offset = self->length;
- }
- }
- else
- {
- offset += self->length + 1;
- if (offset < 0)
- {
- offset = 0;
- }
- }
- result = &(self->content[offset]);
- }
- return result;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Extract the content.
-
- @param self Dynamic String
- @return Content of dynamic string.
-
- The content is removed from the dynamic string. This enables destruction
- of the dynamic string without deallocation of the content.
-*/
-TRIO_STRING_PUBLIC char *
-trio_string_extract
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- char *result;
-
- assert(self);
-
- result = self->content;
- /* FIXME: Allocate new empty buffer? */
- self->content = NULL;
- self->length = self->allocated = 0;
- return result;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Set the content of the dynamic string.
-
- @param self Dynamic String
- @param buffer The new content.
-
- Sets the content of the dynamic string to a copy @p buffer.
- An existing content will be deallocated first, if necessary.
-
- @remark
- This function will make a copy of @p buffer.
- You are responsible for deallocating @p buffer yourself.
-*/
-TRIO_STRING_PUBLIC void
-trio_xstring_set
-TRIO_ARGS2((self, buffer),
- trio_string_t *self,
- char *buffer)
-{
- assert(self);
-
- trio_destroy(self->content);
- self->content = trio_duplicate(buffer);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/*
- * trio_string_size
- */
-TRIO_STRING_PUBLIC int
-trio_string_size
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- return self->allocated;
-}
-
-
-/*
- * trio_string_terminate
- */
-TRIO_STRING_PUBLIC void
-trio_string_terminate
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- trio_xstring_append_char(self, 0);
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Append the second string to the first.
-
- @param self Dynamic string to be modified.
- @param other Dynamic string to copy from.
- @return Boolean value indicating success or failure.
-*/
-TRIO_STRING_PUBLIC int
-trio_string_append
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- size_t length;
-
- assert(self);
- assert(other);
-
- length = self->length + other->length;
- if (!TrioStringGrowTo(self, length))
- goto error;
- trio_copy(&self->content[self->length], other->content);
- self->length = length;
- return TRUE;
-
- error:
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_append
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_append
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- size_t length;
-
- assert(self);
- assert(other);
-
- length = self->length + trio_length(other);
- if (!TrioStringGrowTo(self, length))
- goto error;
- trio_copy(&self->content[self->length], other);
- self->length = length;
- return TRUE;
-
- error:
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/*
- * trio_xstring_append_char
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_append_char
-TRIO_ARGS2((self, character),
- trio_string_t *self,
- char character)
-{
- assert(self);
-
- if ((int)self->length >= trio_string_size(self))
- {
- if (!TrioStringGrow(self, 0))
- goto error;
- }
- self->content[self->length] = character;
- self->length++;
- return TRUE;
-
- error:
- return FALSE;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Search for the first occurrence of second parameter in the first.
-
- @param self Dynamic string to be modified.
- @param other Dynamic string to copy from.
- @return Boolean value indicating success or failure.
-*/
-TRIO_STRING_PUBLIC int
-trio_string_contains
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_contains(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_contains
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_contains
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_contains(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_copy
- */
-TRIO_STRING_PUBLIC int
-trio_string_copy
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- self->length = 0;
- return trio_string_append(self, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_copy
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_copy
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- self->length = 0;
- return trio_xstring_append(self, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_duplicate
- */
-TRIO_STRING_PUBLIC trio_string_t *
-trio_string_duplicate
-TRIO_ARGS1((other),
- trio_string_t *other)
-{
- trio_string_t *self;
-
- assert(other);
-
- self = TrioStringAlloc();
- if (self)
- {
- self->content = TrioDuplicateMax(other->content, other->length);
- if (self->content)
- {
- self->length = other->length;
- self->allocated = self->length + 1;
- }
- else
- {
- self->length = self->allocated = 0;
- }
- }
- return self;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/*
- * trio_xstring_duplicate
- */
-TRIO_STRING_PUBLIC trio_string_t *
-trio_xstring_duplicate
-TRIO_ARGS1((other),
- TRIO_CONST char *other)
-{
- trio_string_t *self;
-
- assert(other);
-
- self = TrioStringAlloc();
- if (self)
- {
- self->content = TrioDuplicateMax(other, trio_length(other));
- if (self->content)
- {
- self->length = trio_length(self->content);
- self->allocated = self->length + 1;
- }
- else
- {
- self->length = self->allocated = 0;
- }
- }
- return self;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_equal
- */
-TRIO_STRING_PUBLIC int
-trio_string_equal
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_equal
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_equal
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_equal_max
- */
-TRIO_STRING_PUBLIC int
-trio_string_equal_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_max(self->content, max, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_equal_max
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_equal_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_max(self->content, max, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_equal_case
- */
-TRIO_STRING_PUBLIC int
-trio_string_equal_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_equal_case
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_equal_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_equal_case_max
- */
-TRIO_STRING_PUBLIC int
-trio_string_equal_case_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case_max(self->content, max, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_equal_case_max
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_equal_case_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case_max(self->content, max, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
-/*
- * trio_string_format_data_max
- */
-TRIO_STRING_PUBLIC size_t
-trio_string_format_date_max
-TRIO_ARGS4((self, max, format, datetime),
- trio_string_t *self,
- size_t max,
- TRIO_CONST char *format,
- TRIO_CONST struct tm *datetime)
-{
- assert(self);
-
- return trio_format_date_max(self->content, max, format, datetime);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_index
- */
-TRIO_STRING_PUBLIC char *
-trio_string_index
-TRIO_ARGS2((self, character),
- trio_string_t *self,
- int character)
-{
- assert(self);
-
- return trio_index(self->content, character);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_index_last
- */
-TRIO_STRING_PUBLIC char *
-trio_string_index_last
-TRIO_ARGS2((self, character),
- trio_string_t *self,
- int character)
-{
- assert(self);
-
- return trio_index_last(self->content, character);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_length
- */
-TRIO_STRING_PUBLIC int
-trio_string_length
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- if (self->length == 0)
- {
- self->length = trio_length(self->content);
- }
- return self->length;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_lower
- */
-TRIO_STRING_PUBLIC int
-trio_string_lower
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- return trio_lower(self->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_match
- */
-TRIO_STRING_PUBLIC int
-trio_string_match
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_match(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_match
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_match
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_match(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_match_case
- */
-TRIO_STRING_PUBLIC int
-trio_string_match_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_match_case(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_match_case
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_match_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_match_case(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_substring
- */
-TRIO_STRING_PUBLIC char *
-trio_string_substring
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_substring(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_substring
- */
-TRIO_STRING_PUBLIC char *
-trio_xstring_substring
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_substring(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_upper
- */
-TRIO_STRING_PUBLIC int
-trio_string_upper
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- return trio_upper(self->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-/** @} End of DynamicStrings */
diff --git a/triostr.h b/triostr.h
deleted file mode 100644
index 0a0e71a..0000000
--- a/triostr.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIOSTR_H
-#define TRIO_TRIOSTR_H
-
-#include
-#include
-#include
-#include
-#include "triodef.h"
-#include "triop.h"
-
-enum {
- TRIO_HASH_NONE = 0,
- TRIO_HASH_PLAIN,
- TRIO_HASH_TWOSIGNED
-};
-
-#if !defined(TRIO_STRING_PUBLIC)
-# if !defined(TRIO_PUBLIC)
-# define TRIO_PUBLIC
-# endif
-# define TRIO_STRING_PUBLIC TRIO_PUBLIC
-#endif
-
-/*************************************************************************
- * String functions
- */
-
-TRIO_STRING_PUBLIC int trio_copy_max TRIO_PROTO((char *target, size_t max, const char *source));
-TRIO_STRING_PUBLIC char *trio_create TRIO_PROTO((size_t size));
-TRIO_STRING_PUBLIC void trio_destroy TRIO_PROTO((char *string));
-TRIO_STRING_PUBLIC char *trio_duplicate TRIO_PROTO((const char *source));
-TRIO_STRING_PUBLIC int trio_equal TRIO_PROTO((const char *first, const char *second));
-TRIO_STRING_PUBLIC int trio_equal_case TRIO_PROTO((const char *first, const char *second));
-TRIO_STRING_PUBLIC int trio_equal_locale TRIO_PROTO((const char *first, const char *second));
-TRIO_STRING_PUBLIC int trio_equal_max TRIO_PROTO((const char *first, size_t max, const char *second));
-TRIO_STRING_PUBLIC TRIO_CONST char *trio_error TRIO_PROTO((int));
-TRIO_STRING_PUBLIC size_t trio_length TRIO_PROTO((const char *string));
-TRIO_STRING_PUBLIC double trio_to_double TRIO_PROTO((const char *source, char **endp));
-TRIO_STRING_PUBLIC long trio_to_long TRIO_PROTO((const char *source, char **endp, int base));
-TRIO_STRING_PUBLIC trio_long_double_t trio_to_long_double TRIO_PROTO((const char *source, char **endp));
-TRIO_STRING_PUBLIC int trio_to_upper TRIO_PROTO((int source));
-
-#if !defined(TRIO_MINIMAL)
-
-TRIO_STRING_PUBLIC int trio_append TRIO_PROTO((char *target, const char *source));
-TRIO_STRING_PUBLIC int trio_append_max TRIO_PROTO((char *target, size_t max, const char *source));
-TRIO_STRING_PUBLIC int trio_contains TRIO_PROTO((const char *string, const char *substring));
-TRIO_STRING_PUBLIC int trio_copy TRIO_PROTO((char *target, const char *source));
-TRIO_STRING_PUBLIC char *trio_duplicate_max TRIO_PROTO((const char *source, size_t max));
-TRIO_STRING_PUBLIC int trio_equal_case_max TRIO_PROTO((const char *first, size_t max, const char *second));
-#if !defined(_WIN32_WCE)
-TRIO_STRING_PUBLIC size_t trio_format_date_max TRIO_PROTO((char *target, size_t max, const char *format, const struct tm *datetime));
-#endif
-TRIO_STRING_PUBLIC unsigned long trio_hash TRIO_PROTO((const char *string, int type));
-TRIO_STRING_PUBLIC char *trio_index TRIO_PROTO((const char *string, int character));
-TRIO_STRING_PUBLIC char *trio_index_last TRIO_PROTO((const char *string, int character));
-TRIO_STRING_PUBLIC int trio_lower TRIO_PROTO((char *target));
-TRIO_STRING_PUBLIC int trio_match TRIO_PROTO((const char *string, const char *pattern));
-TRIO_STRING_PUBLIC int trio_match_case TRIO_PROTO((const char *string, const char *pattern));
-TRIO_STRING_PUBLIC size_t trio_span_function TRIO_PROTO((char *target, const char *source, int (*Function) TRIO_PROTO((int))));
-TRIO_STRING_PUBLIC char *trio_substring TRIO_PROTO((const char *string, const char *substring));
-TRIO_STRING_PUBLIC char *trio_substring_max TRIO_PROTO((const char *string, size_t max, const char *substring));
-TRIO_STRING_PUBLIC float trio_to_float TRIO_PROTO((const char *source, char **endp));
-TRIO_STRING_PUBLIC int trio_to_lower TRIO_PROTO((int source));
-TRIO_STRING_PUBLIC unsigned long trio_to_unsigned_long TRIO_PROTO((const char *source, char **endp, int base));
-TRIO_STRING_PUBLIC char *trio_tokenize TRIO_PROTO((char *string, const char *delimiters));
-TRIO_STRING_PUBLIC int trio_upper TRIO_PROTO((char *target));
-
-#endif /* !defined(TRIO_MINIMAL) */
-
-/*************************************************************************
- * Dynamic string functions
- */
-
-/*
- * Opaque type for dynamic strings
- */
-
-typedef struct _trio_string_t trio_string_t;
-
-TRIO_STRING_PUBLIC void trio_string_destroy TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC char *trio_string_extract TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC int trio_string_size TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC void trio_string_terminate TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC int trio_xstring_append_char TRIO_PROTO((trio_string_t *self, char character));
-TRIO_STRING_PUBLIC trio_string_t *trio_xstring_duplicate TRIO_PROTO((const char *other));
-
-#if !defined(TRIO_MINIMAL)
-
-TRIO_STRING_PUBLIC trio_string_t *trio_string_create TRIO_PROTO((int initial_size));
-TRIO_STRING_PUBLIC char *trio_string_get TRIO_PROTO((trio_string_t *self, int offset));
-TRIO_STRING_PUBLIC void trio_xstring_set TRIO_PROTO((trio_string_t *self, char *buffer));
-
-TRIO_STRING_PUBLIC int trio_string_append TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_contains TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_copy TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC trio_string_t *trio_string_duplicate TRIO_PROTO((trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_equal TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_equal_max TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second));
-TRIO_STRING_PUBLIC int trio_string_equal_case TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_equal_case_max TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other));
-#if !defined(_WIN32_WCE)
-TRIO_STRING_PUBLIC size_t trio_string_format_date_max TRIO_PROTO((trio_string_t *self, size_t max, const char *format, const struct tm *datetime));
-#endif
-TRIO_STRING_PUBLIC char *trio_string_index TRIO_PROTO((trio_string_t *self, int character));
-TRIO_STRING_PUBLIC char *trio_string_index_last TRIO_PROTO((trio_string_t *self, int character));
-TRIO_STRING_PUBLIC int trio_string_length TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC int trio_string_lower TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC int trio_string_match TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_match_case TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC char *trio_string_substring TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_upper TRIO_PROTO((trio_string_t *self));
-
-TRIO_STRING_PUBLIC int trio_xstring_append TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_contains TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_copy TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_equal TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_equal_max TRIO_PROTO((trio_string_t *self, size_t max, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_equal_case TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_equal_case_max TRIO_PROTO((trio_string_t *self, size_t max, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_match TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_match_case TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC char *trio_xstring_substring TRIO_PROTO((trio_string_t *self, const char *other));
-
-#endif /* !defined(TRIO_MINIMAL) */
-
-#endif /* TRIO_TRIOSTR_H */
diff --git a/uri.c b/uri.c
index 03b5a31..370b449 100644
--- a/uri.c
+++ b/uri.c
@@ -37,23 +37,6 @@
#define PORT_EMPTY 0
#define PORT_EMPTY_SERVER -1
-static void
-xmlURIErrMemory(const char *extra)
-{
- if (extra)
- __xmlRaiseError(NULL, NULL, NULL,
- NULL, NULL, XML_FROM_URI,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
- extra, NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
- else
- __xmlRaiseError(NULL, NULL, NULL,
- NULL, NULL, XML_FROM_URI,
- XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
- NULL, NULL, NULL, 0, 0,
- "Memory allocation failed\n");
-}
-
static void xmlCleanURI(xmlURIPtr uri);
/*
@@ -68,7 +51,6 @@ static void xmlCleanURI(xmlURIPtr uri);
* "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" |
* "u" | "v" | "w" | "x" | "y" | "z"
*/
-
#define IS_LOWALPHA(x) (((x) >= 'a') && ((x) <= 'z'))
/*
@@ -89,7 +71,6 @@ static void xmlCleanURI(xmlURIPtr uri);
/*
* alphanum = alpha | digit
*/
-
#define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x))
/*
@@ -103,16 +84,15 @@ static void xmlCleanURI(xmlURIPtr uri);
/*
* unwise = "{" | "}" | "|" | "\" | "^" | "`"
*/
-
#define IS_UNWISE(p) \
(((*(p) == '{')) || ((*(p) == '}')) || ((*(p) == '|')) || \
((*(p) == '\\')) || ((*(p) == '^')) || ((*(p) == '[')) || \
((*(p) == ']')) || ((*(p) == '`')))
+
/*
* reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," |
* "[" | "]"
*/
-
#define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \
((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \
((x) == '+') || ((x) == '$') || ((x) == ',') || ((x) == '[') || \
@@ -121,13 +101,11 @@ static void xmlCleanURI(xmlURIPtr uri);
/*
* unreserved = alphanum | mark
*/
-
#define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x))
/*
* Skip to next pointer char, handle escaped sequences
*/
-
#define NEXT(p) ((*p == '%')? p += 3 : p++)
/*
@@ -139,7 +117,6 @@ static void xmlCleanURI(xmlURIPtr uri);
*
* path = [ abs_path | opaque_part ]
*/
-
#define STRNDUP(s, n) (char *) xmlStrndup((const xmlChar *)(s), (n))
/************************************************************************
@@ -181,7 +158,7 @@ static void xmlCleanURI(xmlURIPtr uri);
/*
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
*/
-#define ISA_UNRESERVED(p) \
+#define ISA_STRICTLY_UNRESERVED(p) \
((ISA_ALPHA(p)) || (ISA_DIGIT(p)) || ((*(p) == '-')) || \
((*(p) == '.')) || ((*(p) == '_')) || ((*(p) == '~')))
@@ -194,10 +171,47 @@ static void xmlCleanURI(xmlURIPtr uri);
/*
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*/
-#define ISA_PCHAR(p) \
- (ISA_UNRESERVED(p) || ISA_PCT_ENCODED(p) || ISA_SUB_DELIM(p) || \
+#define ISA_PCHAR(u, p) \
+ (ISA_UNRESERVED(u, p) || ISA_PCT_ENCODED(p) || ISA_SUB_DELIM(p) || \
((*(p) == ':')) || ((*(p) == '@')))
+/*
+ * From https://www.w3.org/TR/leiri/
+ *
+ * " " / "<" / ">" / '"' / "{" / "}" / "|"
+ * / "\" / "^" / "`" / %x0-1F / %x7F-D7FF
+ * / %xE000-FFFD / %x10000-10FFFF
+ */
+#define ISA_UCSCHAR(p) \
+ ((*(p) <= 0x20) || (*(p) >= 0x7F) || (*(p) == '<') || (*(p) == '>') || \
+ (*(p) == '"') || (*(p) == '{') || (*(p) == '}') || (*(p) == '|') || \
+ (*(p) == '\\') || (*(p) == '^') || (*(p) == '`'))
+
+#define ISA_UNRESERVED(u, p) (xmlIsUnreserved(u, p))
+
+#define XML_URI_ALLOW_UNWISE 1
+#define XML_URI_NO_UNESCAPE 2
+#define XML_URI_ALLOW_UCSCHAR 4
+
+static int
+xmlIsUnreserved(xmlURIPtr uri, const char *cur) {
+ if (uri == NULL)
+ return(0);
+
+ if (ISA_STRICTLY_UNRESERVED(cur))
+ return(1);
+
+ if (uri->cleanup & XML_URI_ALLOW_UNWISE) {
+ if (IS_UNWISE(cur))
+ return(1);
+ } else if (uri->cleanup & XML_URI_ALLOW_UCSCHAR) {
+ if (ISA_UCSCHAR(cur))
+ return(1);
+ }
+
+ return(0);
+}
+
/**
* xmlParse3986Scheme:
* @uri: pointer to an URI structure
@@ -213,18 +227,17 @@ static int
xmlParse3986Scheme(xmlURIPtr uri, const char **str) {
const char *cur;
- if (str == NULL)
- return(-1);
-
cur = *str;
if (!ISA_ALPHA(cur))
- return(2);
+ return(1);
cur++;
while (ISA_ALPHA(cur) || ISA_DIGIT(cur) ||
(*cur == '+') || (*cur == '-') || (*cur == '.')) cur++;
if (uri != NULL) {
if (uri->scheme != NULL) xmlFree(uri->scheme);
uri->scheme = STRNDUP(*str, cur - *str);
+ if (uri->scheme == NULL)
+ return(-1);
}
*str = cur;
return(0);
@@ -250,22 +263,20 @@ xmlParse3986Fragment(xmlURIPtr uri, const char **str)
{
const char *cur;
- if (str == NULL)
- return (-1);
-
cur = *str;
- while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') ||
- (*cur == '[') || (*cur == ']') ||
- ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
+ while ((ISA_PCHAR(uri, cur)) || (*cur == '/') || (*cur == '?') ||
+ (*cur == '[') || (*cur == ']'))
NEXT(cur);
if (uri != NULL) {
if (uri->fragment != NULL)
xmlFree(uri->fragment);
- if (uri->cleanup & 2)
+ if (uri->cleanup & XML_URI_NO_UNESCAPE)
uri->fragment = STRNDUP(*str, cur - *str);
else
uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->fragment == NULL)
+ return (-1);
}
*str = cur;
return (0);
@@ -287,21 +298,19 @@ xmlParse3986Query(xmlURIPtr uri, const char **str)
{
const char *cur;
- if (str == NULL)
- return (-1);
-
cur = *str;
- while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') ||
- ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
+ while ((ISA_PCHAR(uri, cur)) || (*cur == '/') || (*cur == '?'))
NEXT(cur);
if (uri != NULL) {
if (uri->query != NULL)
xmlFree(uri->query);
- if (uri->cleanup & 2)
+ if (uri->cleanup & XML_URI_NO_UNESCAPE)
uri->query = STRNDUP(*str, cur - *str);
else
uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->query == NULL)
+ return (-1);
/* Save the raw bytes of the query as well.
* See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00114
@@ -309,6 +318,8 @@ xmlParse3986Query(xmlURIPtr uri, const char **str)
if (uri->query_raw != NULL)
xmlFree (uri->query_raw);
uri->query_raw = STRNDUP (*str, cur - *str);
+ if (uri->query_raw == NULL)
+ return (-1);
}
*str = cur;
return (0);
@@ -371,16 +382,18 @@ xmlParse3986Userinfo(xmlURIPtr uri, const char **str)
const char *cur;
cur = *str;
- while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) ||
+ while (ISA_UNRESERVED(uri, cur) || ISA_PCT_ENCODED(cur) ||
ISA_SUB_DELIM(cur) || (*cur == ':'))
NEXT(cur);
if (*cur == '@') {
if (uri != NULL) {
if (uri->user != NULL) xmlFree(uri->user);
- if (uri->cleanup & 2)
+ if (uri->cleanup & XML_URI_NO_UNESCAPE)
uri->user = STRNDUP(*str, cur - *str);
else
uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->user == NULL)
+ return(-1);
}
*str = cur;
return(0);
@@ -485,7 +498,8 @@ xmlParse3986Host(xmlURIPtr uri, const char **str)
/*
* then this should be a hostname which can be empty
*/
- while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) || ISA_SUB_DELIM(cur))
+ while (ISA_UNRESERVED(uri, cur) ||
+ ISA_PCT_ENCODED(cur) || ISA_SUB_DELIM(cur))
NEXT(cur);
found:
if (uri != NULL) {
@@ -493,10 +507,12 @@ xmlParse3986Host(xmlURIPtr uri, const char **str)
uri->authority = NULL;
if (uri->server != NULL) xmlFree(uri->server);
if (cur != host) {
- if (uri->cleanup & 2)
+ if (uri->cleanup & XML_URI_NO_UNESCAPE)
uri->server = STRNDUP(host, cur - host);
else
uri->server = xmlURIUnescapeString(host, cur - host, NULL);
+ if (uri->server == NULL)
+ return(-1);
} else
uri->server = NULL;
}
@@ -527,6 +543,8 @@ xmlParse3986Authority(xmlURIPtr uri, const char **str)
* try to parse an userinfo and check for the trailing @
*/
ret = xmlParse3986Userinfo(uri, &cur);
+ if (ret < 0)
+ return(ret);
if ((ret != 0) || (*cur != '@'))
cur = *str;
else
@@ -559,17 +577,17 @@ xmlParse3986Authority(xmlURIPtr uri, const char **str)
* Returns 0 or the error code
*/
static int
-xmlParse3986Segment(const char **str, char forbid, int empty)
+xmlParse3986Segment(xmlURIPtr uri, const char **str, char forbid, int empty)
{
const char *cur;
cur = *str;
- if (!ISA_PCHAR(cur)) {
+ if (!ISA_PCHAR(uri, cur)) {
if (empty)
return(0);
return(1);
}
- while (ISA_PCHAR(cur) && (*cur != forbid))
+ while (ISA_PCHAR(uri, cur) && (*cur != forbid))
NEXT(cur);
*str = cur;
return (0);
@@ -597,16 +615,18 @@ xmlParse3986PathAbEmpty(xmlURIPtr uri, const char **str)
while (*cur == '/') {
cur++;
- ret = xmlParse3986Segment(&cur, 0, 1);
+ ret = xmlParse3986Segment(uri, &cur, 0, 1);
if (ret != 0) return(ret);
}
if (uri != NULL) {
if (uri->path != NULL) xmlFree(uri->path);
if (*str != cur) {
- if (uri->cleanup & 2)
+ if (uri->cleanup & XML_URI_NO_UNESCAPE)
uri->path = STRNDUP(*str, cur - *str);
else
uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->path == NULL)
+ return (-1);
} else {
uri->path = NULL;
}
@@ -638,21 +658,23 @@ xmlParse3986PathAbsolute(xmlURIPtr uri, const char **str)
if (*cur != '/')
return(1);
cur++;
- ret = xmlParse3986Segment(&cur, 0, 0);
+ ret = xmlParse3986Segment(uri, &cur, 0, 0);
if (ret == 0) {
while (*cur == '/') {
cur++;
- ret = xmlParse3986Segment(&cur, 0, 1);
+ ret = xmlParse3986Segment(uri, &cur, 0, 1);
if (ret != 0) return(ret);
}
}
if (uri != NULL) {
if (uri->path != NULL) xmlFree(uri->path);
if (cur != *str) {
- if (uri->cleanup & 2)
+ if (uri->cleanup & XML_URI_NO_UNESCAPE)
uri->path = STRNDUP(*str, cur - *str);
else
uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->path == NULL)
+ return (-1);
} else {
uri->path = NULL;
}
@@ -681,20 +703,22 @@ xmlParse3986PathRootless(xmlURIPtr uri, const char **str)
cur = *str;
- ret = xmlParse3986Segment(&cur, 0, 0);
+ ret = xmlParse3986Segment(uri, &cur, 0, 0);
if (ret != 0) return(ret);
while (*cur == '/') {
cur++;
- ret = xmlParse3986Segment(&cur, 0, 1);
+ ret = xmlParse3986Segment(uri, &cur, 0, 1);
if (ret != 0) return(ret);
}
if (uri != NULL) {
if (uri->path != NULL) xmlFree(uri->path);
if (cur != *str) {
- if (uri->cleanup & 2)
+ if (uri->cleanup & XML_URI_NO_UNESCAPE)
uri->path = STRNDUP(*str, cur - *str);
else
uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->path == NULL)
+ return (-1);
} else {
uri->path = NULL;
}
@@ -723,20 +747,22 @@ xmlParse3986PathNoScheme(xmlURIPtr uri, const char **str)
cur = *str;
- ret = xmlParse3986Segment(&cur, ':', 0);
+ ret = xmlParse3986Segment(uri, &cur, ':', 0);
if (ret != 0) return(ret);
while (*cur == '/') {
cur++;
- ret = xmlParse3986Segment(&cur, 0, 1);
+ ret = xmlParse3986Segment(uri, &cur, 0, 1);
if (ret != 0) return(ret);
}
if (uri != NULL) {
if (uri->path != NULL) xmlFree(uri->path);
if (cur != *str) {
- if (uri->cleanup & 2)
+ if (uri->cleanup & XML_URI_NO_UNESCAPE)
uri->path = STRNDUP(*str, cur - *str);
else
uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->path == NULL)
+ return (-1);
} else {
uri->path = NULL;
}
@@ -784,7 +810,7 @@ xmlParse3986HierPart(xmlURIPtr uri, const char **str)
} else if (*cur == '/') {
ret = xmlParse3986PathAbsolute(uri, &cur);
if (ret != 0) return(ret);
- } else if (ISA_PCHAR(cur)) {
+ } else if (ISA_PCHAR(uri, cur)) {
ret = xmlParse3986PathRootless(uri, &cur);
if (ret != 0) return(ret);
} else {
@@ -827,7 +853,7 @@ xmlParse3986RelativeRef(xmlURIPtr uri, const char *str) {
} else if (*str == '/') {
ret = xmlParse3986PathAbsolute(uri, &str);
if (ret != 0) return(ret);
- } else if (ISA_PCHAR(str)) {
+ } else if (ISA_PCHAR(uri, str)) {
ret = xmlParse3986PathNoScheme(uri, &str);
if (ret != 0) return(ret);
} else {
@@ -922,6 +948,8 @@ xmlParse3986URIReference(xmlURIPtr uri, const char *str) {
* it fails.
*/
ret = xmlParse3986URI(uri, str);
+ if (ret < 0)
+ return(ret);
if (ret != 0) {
xmlCleanURI(uri);
ret = xmlParse3986RelativeRef(uri, str);
@@ -934,30 +962,58 @@ xmlParse3986URIReference(xmlURIPtr uri, const char *str) {
}
/**
- * xmlParseURI:
+ * xmlParseURISafe:
* @str: the URI string to analyze
+ * @uriOut: optional pointer to parsed URI
*
* Parse an URI based on RFC 3986
*
* URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
*
- * Returns a newly built xmlURIPtr or NULL in case of error
+ * Available since 2.13.0.
+ *
+ * Returns 0 on success, an error code (typically 1) if the URI is invalid
+ * or -1 if a memory allocation failed.
*/
-xmlURIPtr
-xmlParseURI(const char *str) {
+int
+xmlParseURISafe(const char *str, xmlURIPtr *uriOut) {
xmlURIPtr uri;
int ret;
+ if (uriOut == NULL)
+ return(1);
+ *uriOut = NULL;
if (str == NULL)
- return(NULL);
+ return(1);
+
uri = xmlCreateURI();
- if (uri != NULL) {
- ret = xmlParse3986URIReference(uri, str);
- if (ret) {
- xmlFreeURI(uri);
- return(NULL);
- }
+ if (uri == NULL)
+ return(-1);
+
+ ret = xmlParse3986URIReference(uri, str);
+ if (ret) {
+ xmlFreeURI(uri);
+ return(ret);
}
+
+ *uriOut = uri;
+ return(0);
+}
+
+/**
+ * xmlParseURI:
+ * @str: the URI string to analyze
+ *
+ * Parse an URI based on RFC 3986
+ *
+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+ *
+ * Returns a newly built xmlURIPtr or NULL in case of error
+ */
+xmlURIPtr
+xmlParseURI(const char *str) {
+ xmlURIPtr uri;
+ xmlParseURISafe(str, &uri);
return(uri);
}
@@ -999,7 +1055,7 @@ xmlParseURIRaw(const char *str, int raw) {
uri = xmlCreateURI();
if (uri != NULL) {
if (raw) {
- uri->cleanup |= 2;
+ uri->cleanup |= XML_URI_NO_UNESCAPE;
}
ret = xmlParseURIReference(uri, str);
if (ret) {
@@ -1028,10 +1084,8 @@ xmlCreateURI(void) {
xmlURIPtr ret;
ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI));
- if (ret == NULL) {
- xmlURIErrMemory("creating URI structure\n");
+ if (ret == NULL)
return(NULL);
- }
memset(ret, 0, sizeof(xmlURI));
ret->port = PORT_EMPTY;
return(ret);
@@ -1048,16 +1102,12 @@ xmlSaveUriRealloc(xmlChar *ret, int *max) {
xmlChar *temp;
int tmp;
- if (*max > MAX_URI_LENGTH) {
- xmlURIErrMemory("reaching arbitrary MAX_URI_LENGTH limit\n");
+ if (*max > MAX_URI_LENGTH)
return(NULL);
- }
tmp = *max * 2;
temp = (xmlChar *) xmlRealloc(ret, (tmp + 1));
- if (temp == NULL) {
- xmlURIErrMemory("saving URI\n");
+ if (temp == NULL)
return(NULL);
- }
*max = tmp;
return(temp);
}
@@ -1083,10 +1133,8 @@ xmlSaveUri(xmlURIPtr uri) {
max = 80;
ret = (xmlChar *) xmlMallocAtomic(max + 1);
- if (ret == NULL) {
- xmlURIErrMemory("saving URI\n");
+ if (ret == NULL)
return(NULL);
- }
len = 0;
if (uri->scheme != NULL) {
@@ -1414,195 +1462,136 @@ xmlFreeURI(xmlURIPtr uri) {
* *
************************************************************************/
+static int
+xmlIsPathSeparator(int c, int isFile) {
+ (void) isFile;
+
+ if (c == '/')
+ return(1);
+
+#ifdef _WIN32
+ if (isFile && (c == '\\'))
+ return(1);
+#endif
+
+ return(0);
+}
+
/**
- * xmlNormalizeURIPath:
+ * xmlNormalizePath:
* @path: pointer to the path string
+ * @isFile: true for filesystem paths, false for URIs
*
- * Applies the 5 normalization steps to a path string--that is, RFC 2396
- * Section 5.2, steps 6.c through 6.g.
- *
- * Normalization occurs directly on the string, no new allocation is done
+ * Normalize a filesystem path or URI.
*
* Returns 0 or an error code
*/
-int
-xmlNormalizeURIPath(char *path) {
+static int
+xmlNormalizePath(char *path, int isFile) {
char *cur, *out;
+ int numSeg = 0;
if (path == NULL)
return(-1);
- /* Skip all initial "/" chars. We want to get to the beginning of the
- * first non-empty segment.
- */
cur = path;
- while (cur[0] == '/')
- ++cur;
- if (cur[0] == '\0')
- return(0);
-
- /* Keep everything we've seen so far. */
- out = cur;
-
- /*
- * Analyze each segment in sequence for cases (c) and (d).
- */
- while (cur[0] != '\0') {
- /*
- * c) All occurrences of "./", where "." is a complete path segment,
- * are removed from the buffer string.
- */
- if ((cur[0] == '.') && (cur[1] == '/')) {
- cur += 2;
- /* '//' normalization should be done at this point too */
- while (cur[0] == '/')
- cur++;
- continue;
- }
+ out = path;
- /*
- * d) If the buffer string ends with "." as a complete path segment,
- * that "." is removed.
- */
- if ((cur[0] == '.') && (cur[1] == '\0'))
- break;
-
- /* Otherwise keep the segment. */
- while (cur[0] != '/') {
- if (cur[0] == '\0')
- goto done_cd;
- (out++)[0] = (cur++)[0];
- }
- /* normalize // */
- while ((cur[0] == '/') && (cur[1] == '/'))
- cur++;
+ if (*cur == 0)
+ return(0);
- (out++)[0] = (cur++)[0];
+ if (xmlIsPathSeparator(*cur, isFile)) {
+ cur++;
+ *out++ = '/';
}
- done_cd:
- out[0] = '\0';
-
- /* Reset to the beginning of the first segment for the next sequence. */
- cur = path;
- while (cur[0] == '/')
- ++cur;
- if (cur[0] == '\0')
- return(0);
-
- /*
- * Analyze each segment in sequence for cases (e) and (f).
- *
- * e) All occurrences of "/../", where is a
- * complete path segment not equal to "..", are removed from the
- * buffer string. Removal of these path segments is performed
- * iteratively, removing the leftmost matching pattern on each
- * iteration, until no matching pattern remains.
- *
- * f) If the buffer string ends with "/..", where
- * is a complete path segment not equal to "..", that
- * "/.." is removed.
- *
- * To satisfy the "iterative" clause in (e), we need to collapse the
- * string every time we find something that needs to be removed. Thus,
- * we don't need to keep two pointers into the string: we only need a
- * "current position" pointer.
- */
- while (1) {
- char *segp, *tmp;
-
- /* At the beginning of each iteration of this loop, "cur" points to
- * the first character of the segment we want to examine.
- */
-
- /* Find the end of the current segment. */
- segp = cur;
- while ((segp[0] != '/') && (segp[0] != '\0'))
- ++segp;
- /* If this is the last segment, we're done (we need at least two
- * segments to meet the criteria for the (e) and (f) cases).
- */
- if (segp[0] == '\0')
- break;
-
- /* If the first segment is "..", or if the next segment _isn't_ "..",
- * keep this segment and try the next one.
+ while (*cur != 0) {
+ /*
+ * At this point, out is either empty or ends with a separator.
+ * Collapse multiple separators first.
*/
- ++segp;
- if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3))
- || ((segp[0] != '.') || (segp[1] != '.')
- || ((segp[2] != '/') && (segp[2] != '\0')))) {
- cur = segp;
- continue;
+ while (xmlIsPathSeparator(*cur, isFile)) {
+#ifdef _WIN32
+ /* Allow two separators at start of path */
+ if ((isFile) && (out == path + 1))
+ *out++ = '/';
+#endif
+ cur++;
}
- /* If we get here, remove this segment and the next one and back up
- * to the previous segment (if there is one), to implement the
- * "iteratively" clause. It's pretty much impossible to back up
- * while maintaining two pointers into the buffer, so just compact
- * the whole buffer now.
- */
+ if (*cur == '.') {
+ if (cur[1] == 0) {
+ /* Ignore "." at end of path */
+ break;
+ } else if (xmlIsPathSeparator(cur[1], isFile)) {
+ /* Skip "./" */
+ cur += 2;
+ continue;
+ } else if ((cur[1] == '.') &&
+ ((cur[2] == 0) || xmlIsPathSeparator(cur[2], isFile))) {
+ if (numSeg > 0) {
+ /* Handle ".." by removing last segment */
+ do {
+ out--;
+ } while ((out > path) &&
+ !xmlIsPathSeparator(out[-1], isFile));
+ numSeg--;
+
+ if (cur[2] == 0)
+ break;
+ cur += 3;
+ continue;
+ } else if (out[0] == '/') {
+ /* Ignore extraneous ".." in absolute paths */
+ if (cur[2] == 0)
+ break;
+ cur += 3;
+ continue;
+ } else {
+ /* Keep "../" at start of relative path */
+ numSeg--;
+ }
+ }
+ }
- /* If this is the end of the buffer, we're done. */
- if (segp[2] == '\0') {
- cur[0] = '\0';
- break;
+ /* Copy segment */
+ while ((*cur != 0) && !xmlIsPathSeparator(*cur, isFile)) {
+ *out++ = *cur++;
}
- /* Valgrind complained, strcpy(cur, segp + 3); */
- /* string will overlap, do not use strcpy */
- tmp = cur;
- segp += 3;
- while ((*tmp++ = *segp++) != 0)
- ;
-
- /* If there are no previous segments, then keep going from here. */
- segp = cur;
- while ((segp > path) && ((--segp)[0] == '/'))
- ;
- if (segp == path)
- continue;
-
- /* "segp" is pointing to the end of a previous segment; find it's
- * start. We need to back up to the previous segment and start
- * over with that to handle things like "foo/bar/../..". If we
- * don't do this, then on the first pass we'll remove the "bar/..",
- * but be pointing at the second ".." so we won't realize we can also
- * remove the "foo/..".
- */
- cur = segp;
- while ((cur > path) && (cur[-1] != '/'))
- --cur;
- }
- out[0] = '\0';
- /*
- * g) If the resulting buffer string still begins with one or more
- * complete path segments of "..", then the reference is
- * considered to be in error. Implementations may handle this
- * error by retaining these components in the resolved path (i.e.,
- * treating them as part of the final URI), by removing them from
- * the resolved path (i.e., discarding relative levels above the
- * root), or by avoiding traversal of the reference.
- *
- * We discard them from the final path.
- */
- if (path[0] == '/') {
- cur = path;
- while ((cur[0] == '/') && (cur[1] == '.') && (cur[2] == '.')
- && ((cur[3] == '/') || (cur[3] == '\0')))
- cur += 3;
+ /* Copy separator */
+ if (*cur != 0) {
+ cur++;
+ *out++ = '/';
+ }
- if (cur != path) {
- out = path;
- while (cur[0] != '\0')
- (out++)[0] = (cur++)[0];
- out[0] = 0;
- }
+ numSeg++;
}
+ /* Keep "." if output is empty and it's a file */
+ if ((isFile) && (out <= path))
+ *out++ = '.';
+ *out = 0;
+
return(0);
}
+/**
+ * xmlNormalizeURIPath:
+ * @path: pointer to the path string
+ *
+ * Applies the 5 normalization steps to a path string--that is, RFC 2396
+ * Section 5.2, steps 6.c through 6.g.
+ *
+ * Normalization occurs directly on the string, no new allocation is done
+ *
+ * Returns 0 or an error code
+ */
+int
+xmlNormalizeURIPath(char *path) {
+ return(xmlNormalizePath(path, 0));
+}
+
static int is_hex(char c) {
if (((c >= '0') && (c <= '9')) ||
((c >= 'a') && (c <= 'f')) ||
@@ -1637,10 +1626,8 @@ xmlURIUnescapeString(const char *str, int len, char *target) {
if (target == NULL) {
ret = (char *) xmlMallocAtomic(len + 1);
- if (ret == NULL) {
- xmlURIErrMemory("unescaping URI value\n");
+ if (ret == NULL)
return(NULL);
- }
} else
ret = target;
in = str;
@@ -1680,8 +1667,9 @@ xmlURIUnescapeString(const char *str, int len, char *target) {
* @str: string to escape
* @list: exception list string of chars not to escape
*
- * This routine escapes a string to hex, ignoring reserved characters
- * (a-z, A-Z, 0-9, "@-_.!~*'()") and the characters in the exception list.
+ * This routine escapes a string to hex, ignoring unreserved characters
+ * a-z, A-Z, 0-9, "-._~", a few sub-delims "!*'()", the gen-delim "@"
+ * (why?) and the characters in the exception list.
*
* Returns a new escaped string or NULL in case of error.
*/
@@ -1697,25 +1685,24 @@ xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) {
if (str[0] == 0)
return(xmlStrdup(str));
len = xmlStrlen(str);
- if (!(len > 0)) return(NULL);
len += 20;
ret = (xmlChar *) xmlMallocAtomic(len);
- if (ret == NULL) {
- xmlURIErrMemory("escaping URI value\n");
+ if (ret == NULL)
return(NULL);
- }
in = (const xmlChar *) str;
out = 0;
while(*in != 0) {
if (len - out <= 3) {
- temp = xmlSaveUriRealloc(ret, &len);
+ if (len > INT_MAX / 2)
+ return(NULL);
+ temp = xmlRealloc(ret, len * 2);
if (temp == NULL) {
- xmlURIErrMemory("escaping URI value\n");
xmlFree(ret);
return(NULL);
}
ret = temp;
+ len *= 2;
}
ch = *in;
@@ -1773,7 +1760,7 @@ xmlURIEscape(const xmlChar * str)
/*
* Allow escaping errors in the unescaped form
*/
- uri->cleanup = 1;
+ uri->cleanup = XML_URI_ALLOW_UNWISE;
ret2 = xmlParseURIReference(uri, (const char *)str);
if (ret2) {
xmlFreeURI(uri);
@@ -1787,7 +1774,6 @@ xmlURIEscape(const xmlChar * str)
ret = NULL;
#define NULLCHK(p) if(!p) { \
- xmlURIErrMemory("escaping URI value\n"); \
xmlFreeURI(uri); \
xmlFree(ret); \
return NULL; } \
@@ -1883,10 +1869,132 @@ xmlURIEscape(const xmlChar * str)
* *
************************************************************************/
+static int
+xmlIsAbsolutePath(const xmlChar *path) {
+ int c = path[0];
+
+ if (xmlIsPathSeparator(c, 1))
+ return(1);
+
+#ifdef _WIN32
+ if ((((c >= 'A') && (c <= 'Z')) ||
+ ((c >= 'a') && (c <= 'z'))) &&
+ (path[1] == ':'))
+ return(1);
+#endif
+
+ return(0);
+}
+
/**
- * xmlBuildURI:
+ * xmlResolvePath:
+ * @ref: the filesystem path
+ * @base: the base value
+ * @out: pointer to result URI
+ *
+ * Resolves a filesystem path from a base path.
+ *
+ * Returns 0 on success, -1 if a memory allocation failed or an error
+ * code if URI or base are invalid.
+ */
+static int
+xmlResolvePath(const xmlChar *escRef, const xmlChar *base, xmlChar **out) {
+ const xmlChar *fragment;
+ xmlChar *tmp = NULL;
+ xmlChar *ref = NULL;
+ xmlChar *result = NULL;
+ int ret = -1;
+ int i;
+
+ if (out == NULL)
+ return(1);
+ *out = NULL;
+
+ if ((escRef == NULL) || (escRef[0] == 0)) {
+ if ((base == NULL) || (base[0] == 0))
+ return(1);
+ ref = xmlStrdup(base);
+ if (ref == NULL)
+ goto err_memory;
+ *out = ref;
+ return(0);
+ }
+
+ /*
+ * If a URI is resolved, we can assume it is a valid URI and not
+ * a filesystem path. This means we have to unescape the part
+ * before the fragment.
+ */
+ fragment = xmlStrchr(escRef, '#');
+ if (fragment != NULL) {
+ tmp = xmlStrndup(escRef, fragment - escRef);
+ if (tmp == NULL)
+ goto err_memory;
+ escRef = tmp;
+ }
+
+ ref = (xmlChar *) xmlURIUnescapeString((char *) escRef, -1, NULL);
+ if (ref == NULL)
+ goto err_memory;
+
+ if ((base == NULL) || (base[0] == 0))
+ goto done;
+
+ if (xmlIsAbsolutePath(ref))
+ goto done;
+
+ /*
+ * Remove last segment from base
+ */
+ i = xmlStrlen(base);
+ while ((i > 0) && !xmlIsPathSeparator(base[i-1], 1))
+ i--;
+
+ /*
+ * Concatenate base and ref
+ */
+ if (i > 0) {
+ int refLen = xmlStrlen(ref);
+
+ result = xmlMalloc(i + refLen + 1);
+ if (result == NULL)
+ goto err_memory;
+
+ memcpy(result, base, i);
+ memcpy(result + i, ref, refLen + 1);
+ }
+
+ /*
+ * Normalize
+ */
+ xmlNormalizePath((char *) result, 1);
+
+done:
+ if (result == NULL) {
+ result = ref;
+ ref = NULL;
+ }
+
+ if (fragment != NULL) {
+ result = xmlStrcat(result, fragment);
+ if (result == NULL)
+ goto err_memory;
+ }
+
+ *out = result;
+ ret = 0;
+
+err_memory:
+ xmlFree(tmp);
+ xmlFree(ref);
+ return(ret);
+}
+
+/**
+ * xmlBuildURISafe:
* @URI: the URI instance found in the document
* @base: the base value
+ * @valPtr: pointer to result URI
*
* Computes he final URI of the reference done by checking that
* the given URI is valid, and building the final URI using the
@@ -1895,17 +2003,22 @@ xmlURIEscape(const xmlChar * str)
*
* 5.2. Resolving Relative References to Absolute Form
*
- * Returns a new URI string (to be freed by the caller) or NULL in case
- * of error.
+ * Available since 2.13.0.
+ *
+ * Returns 0 on success, -1 if a memory allocation failed or an error
+ * code if URI or base are invalid.
*/
-xmlChar *
-xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
+int
+xmlBuildURISafe(const xmlChar *URI, const xmlChar *base, xmlChar **valPtr) {
xmlChar *val = NULL;
int ret, len, indx, cur, out;
xmlURIPtr ref = NULL;
xmlURIPtr bas = NULL;
xmlURIPtr res = NULL;
+ if (valPtr == NULL)
+ return(1);
+
/*
* 1) The URI reference is parsed into the potential four components and
* fragment identifier, as described in Section 4.3.
@@ -1915,17 +2028,11 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
* URI. Should we do that here?
*/
if (URI == NULL)
- ret = -1;
- else {
- if (*URI) {
- ref = xmlCreateURI();
- if (ref == NULL)
- goto done;
- ret = xmlParseURIReference(ref, (const char *) URI);
- }
- else
- ret = 0;
- }
+ ret = 1;
+ else if (URI[0] != 0)
+ ret = xmlParseURISafe((const char *) URI, &ref);
+ else
+ ret = 0;
if (ret != 0)
goto done;
if ((ref != NULL) && (ref->scheme != NULL)) {
@@ -1933,19 +2040,30 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
* The URI is absolute don't modify.
*/
val = xmlStrdup(URI);
+ if (val == NULL)
+ ret = -1;
goto done;
}
- if (base == NULL)
- ret = -1;
- else {
- bas = xmlCreateURI();
- if (bas == NULL)
- goto done;
- ret = xmlParseURIReference(bas, (const char *) base);
+
+ /*
+ * If base has no scheme or authority, it is assumed to be a
+ * filesystem path.
+ */
+ if (xmlStrstr(base, BAD_CAST "://") == NULL) {
+ xmlFreeURI(ref);
+ return(xmlResolvePath(URI, base, valPtr));
}
+
+ ret = xmlParseURISafe((const char *) base, &bas);
+ if (ret < 0)
+ goto done;
if (ret != 0) {
- if (ref)
+ if (ref) {
+ ret = 0;
val = xmlSaveUri(ref);
+ if (val == NULL)
+ ret = -1;
+ }
goto done;
}
if (ref == NULL) {
@@ -1957,6 +2075,8 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
bas->fragment = NULL;
}
val = xmlSaveUri(bas);
+ if (val == NULL)
+ ret = -1;
goto done;
}
@@ -1972,35 +2092,62 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
* defined while still treating this as a reference to the current
* document.
*/
+ ret = -1;
res = xmlCreateURI();
if (res == NULL)
goto done;
if ((ref->scheme == NULL) && (ref->path == NULL) &&
((ref->authority == NULL) && (ref->server == NULL) &&
(ref->port == PORT_EMPTY))) {
- if (bas->scheme != NULL)
+ if (bas->scheme != NULL) {
res->scheme = xmlMemStrdup(bas->scheme);
- if (bas->authority != NULL)
+ if (res->scheme == NULL)
+ goto done;
+ }
+ if (bas->authority != NULL) {
res->authority = xmlMemStrdup(bas->authority);
- else {
- if (bas->server != NULL)
+ if (res->authority == NULL)
+ goto done;
+ } else {
+ if (bas->server != NULL) {
res->server = xmlMemStrdup(bas->server);
- if (bas->user != NULL)
+ if (res->server == NULL)
+ goto done;
+ }
+ if (bas->user != NULL) {
res->user = xmlMemStrdup(bas->user);
+ if (res->user == NULL)
+ goto done;
+ }
res->port = bas->port;
}
- if (bas->path != NULL)
+ if (bas->path != NULL) {
res->path = xmlMemStrdup(bas->path);
- if (ref->query_raw != NULL)
+ if (res->path == NULL)
+ goto done;
+ }
+ if (ref->query_raw != NULL) {
res->query_raw = xmlMemStrdup (ref->query_raw);
- else if (ref->query != NULL)
+ if (res->query_raw == NULL)
+ goto done;
+ } else if (ref->query != NULL) {
res->query = xmlMemStrdup(ref->query);
- else if (bas->query_raw != NULL)
+ if (res->query == NULL)
+ goto done;
+ } else if (bas->query_raw != NULL) {
res->query_raw = xmlMemStrdup(bas->query_raw);
- else if (bas->query != NULL)
+ if (res->query_raw == NULL)
+ goto done;
+ } else if (bas->query != NULL) {
res->query = xmlMemStrdup(bas->query);
- if (ref->fragment != NULL)
+ if (res->query == NULL)
+ goto done;
+ }
+ if (ref->fragment != NULL) {
res->fragment = xmlMemStrdup(ref->fragment);
+ if (res->fragment == NULL)
+ goto done;
+ }
goto step_7;
}
@@ -2012,17 +2159,30 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
*/
if (ref->scheme != NULL) {
val = xmlSaveUri(ref);
+ if (val != NULL)
+ ret = 0;
goto done;
}
- if (bas->scheme != NULL)
+ if (bas->scheme != NULL) {
res->scheme = xmlMemStrdup(bas->scheme);
+ if (res->scheme == NULL)
+ goto done;
+ }
- if (ref->query_raw != NULL)
+ if (ref->query_raw != NULL) {
res->query_raw = xmlMemStrdup(ref->query_raw);
- else if (ref->query != NULL)
+ if (res->query_raw == NULL)
+ goto done;
+ } else if (ref->query != NULL) {
res->query = xmlMemStrdup(ref->query);
- if (ref->fragment != NULL)
+ if (res->query == NULL)
+ goto done;
+ }
+ if (ref->fragment != NULL) {
res->fragment = xmlMemStrdup(ref->fragment);
+ if (res->fragment == NULL)
+ goto done;
+ }
/*
* 4) If the authority component is defined, then the reference is a
@@ -2033,26 +2193,45 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
*/
if ((ref->authority != NULL) || (ref->server != NULL) ||
(ref->port != PORT_EMPTY)) {
- if (ref->authority != NULL)
+ if (ref->authority != NULL) {
res->authority = xmlMemStrdup(ref->authority);
- else {
- if (ref->server != NULL)
+ if (res->authority == NULL)
+ goto done;
+ } else {
+ if (ref->server != NULL) {
res->server = xmlMemStrdup(ref->server);
- if (ref->user != NULL)
+ if (res->server == NULL)
+ goto done;
+ }
+ if (ref->user != NULL) {
res->user = xmlMemStrdup(ref->user);
+ if (res->user == NULL)
+ goto done;
+ }
res->port = ref->port;
}
- if (ref->path != NULL)
+ if (ref->path != NULL) {
res->path = xmlMemStrdup(ref->path);
+ if (res->path == NULL)
+ goto done;
+ }
goto step_7;
}
- if (bas->authority != NULL)
+ if (bas->authority != NULL) {
res->authority = xmlMemStrdup(bas->authority);
- else if ((bas->server != NULL) || (bas->port != PORT_EMPTY)) {
- if (bas->server != NULL)
+ if (res->authority == NULL)
+ goto done;
+ } else if ((bas->server != NULL) || (bas->port != PORT_EMPTY)) {
+ if (bas->server != NULL) {
res->server = xmlMemStrdup(bas->server);
- if (bas->user != NULL)
+ if (res->server == NULL)
+ goto done;
+ }
+ if (bas->user != NULL) {
res->user = xmlMemStrdup(bas->user);
+ if (res->user == NULL)
+ goto done;
+ }
res->port = bas->port;
}
@@ -2062,6 +2241,8 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
*/
if ((ref->path != NULL) && (ref->path[0] == '/')) {
res->path = xmlMemStrdup(ref->path);
+ if (res->path == NULL)
+ goto done;
goto step_7;
}
@@ -2080,10 +2261,8 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
if (bas->path != NULL)
len += strlen(bas->path);
res->path = (char *) xmlMallocAtomic(len);
- if (res->path == NULL) {
- xmlURIErrMemory("resolving URI against base\n");
+ if (res->path == NULL)
goto done;
- }
res->path[0] = 0;
/*
@@ -2139,6 +2318,8 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
* reference.
*/
val = xmlSaveUri(res);
+ if (val != NULL)
+ ret = 0;
done:
if (ref != NULL)
@@ -2147,13 +2328,38 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
xmlFreeURI(bas);
if (res != NULL)
xmlFreeURI(res);
- return(val);
+ *valPtr = val;
+ return(ret);
}
/**
- * xmlBuildRelativeURI:
+ * xmlBuildURI:
+ * @URI: the URI instance found in the document
+ * @base: the base value
+ *
+ * Computes he final URI of the reference done by checking that
+ * the given URI is valid, and building the final URI using the
+ * base URI. This is processed according to section 5.2 of the
+ * RFC 2396
+ *
+ * 5.2. Resolving Relative References to Absolute Form
+ *
+ * Returns a new URI string (to be freed by the caller) or NULL in case
+ * of error.
+ */
+xmlChar *
+xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
+ xmlChar *out;
+
+ xmlBuildURISafe(URI, base, &out);
+ return(out);
+}
+
+/**
+ * xmlBuildRelativeURISafe:
* @URI: the URI reference under consideration
* @base: the base value
+ * @valPtr: pointer to result URI
*
* Expresses the URI of the reference in terms relative to the
* base. Some examples of this operation include:
@@ -2179,14 +2385,17 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
* since this routine (for reasonable efficiency) assumes URI has
* already been through some validation.
*
- * Returns a new URI string (to be freed by the caller) or NULL in case
- * error.
+ * Available since 2.13.0.
+ *
+ * Returns 0 on success, -1 if a memory allocation failed or an error
+ * code if URI or base are invalid.
*/
-xmlChar *
-xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
+int
+xmlBuildRelativeURISafe(const xmlChar * URI, const xmlChar * base,
+ xmlChar **valPtr)
{
xmlChar *val = NULL;
- int ret;
+ int ret = 0;
int ix;
int nbslash = 0;
int len;
@@ -2195,39 +2404,58 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
xmlChar *bptr, *uptr, *vptr;
int remove_path = 0;
+ if (valPtr == NULL)
+ return(1);
+ *valPtr = NULL;
if ((URI == NULL) || (*URI == 0))
- return NULL;
+ return(1);
/*
* First parse URI into a standard form
*/
ref = xmlCreateURI ();
- if (ref == NULL)
- return NULL;
+ if (ref == NULL) {
+ ret = -1;
+ goto done;
+ }
/* If URI not already in "relative" form */
if (URI[0] != '.') {
ret = xmlParseURIReference (ref, (const char *) URI);
if (ret != 0)
goto done; /* Error in URI, return NULL */
- } else
+ } else {
ref->path = (char *)xmlStrdup(URI);
+ if (ref->path == NULL) {
+ ret = -1;
+ goto done;
+ }
+ }
/*
* Next parse base into the same standard form
*/
if ((base == NULL) || (*base == 0)) {
val = xmlStrdup (URI);
+ if (val == NULL)
+ ret = -1;
goto done;
}
bas = xmlCreateURI ();
- if (bas == NULL)
+ if (bas == NULL) {
+ ret = -1;
goto done;
+ }
if (base[0] != '.') {
ret = xmlParseURIReference (bas, (const char *) base);
if (ret != 0)
goto done; /* Error in base, return NULL */
- } else
+ } else {
bas->path = (char *)xmlStrdup(base);
+ if (bas->path == NULL) {
+ ret = -1;
+ goto done;
+ }
+ }
/*
* If the scheme / server on the URI differs from the base,
@@ -2239,14 +2467,20 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
(xmlStrcmp ((xmlChar *)bas->server, (xmlChar *)ref->server)) ||
(bas->port != ref->port))) {
val = xmlStrdup (URI);
+ if (val == NULL)
+ ret = -1;
goto done;
}
if (xmlStrEqual((xmlChar *)bas->path, (xmlChar *)ref->path)) {
val = xmlStrdup(BAD_CAST "");
+ if (val == NULL)
+ ret = -1;
goto done;
}
if (bas->path == NULL) {
val = xmlStrdup((xmlChar *)ref->path);
+ if (val == NULL)
+ ret = -1;
goto done;
}
if (ref->path == NULL) {
@@ -2279,6 +2513,8 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
if (bptr[pos] == rptr[pos]) {
val = xmlStrdup(BAD_CAST "");
+ if (val == NULL)
+ ret = -1;
goto done; /* (I can't imagine why anyone would do this) */
}
@@ -2306,6 +2542,8 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
*/
if (nbslash == 0 && !uptr[0]) {
val = xmlStrdup(BAD_CAST "./");
+ if (val == NULL)
+ ret = -1;
goto done;
}
@@ -2313,9 +2551,12 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
}
if (nbslash == 0) {
- if (uptr != NULL)
+ if (uptr != NULL) {
/* exception characters from xmlSaveUri */
val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,");
+ if (val == NULL)
+ ret = -1;
+ }
goto done;
}
@@ -2326,7 +2567,7 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
*/
val = (xmlChar *) xmlMalloc (len + 3 * nbslash);
if (val == NULL) {
- xmlURIErrMemory("building relative URI\n");
+ ret = -1;
goto done;
}
vptr = val;
@@ -2358,6 +2599,10 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
vptr = val;
/* exception characters from xmlSaveUri */
val = xmlURIEscapeStr(vptr, BAD_CAST "/;&=+$,");
+ if (val == NULL)
+ ret = -1;
+ else
+ ret = 0;
xmlFree(vptr);
done:
@@ -2370,153 +2615,75 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
xmlFreeURI (ref);
if (bas != NULL)
xmlFreeURI (bas);
+ if (ret != 0) {
+ xmlFree(val);
+ val = NULL;
+ }
+
+ *valPtr = val;
+ return(ret);
+}
+
+/*
+ * xmlBuildRelativeURI:
+ * @URI: the URI reference under consideration
+ * @base: the base value
+ *
+ * See xmlBuildRelativeURISafe.
+ *
+ * Returns a new URI string (to be freed by the caller) or NULL in case
+ * error.
+ */
+xmlChar *
+xmlBuildRelativeURI(const xmlChar * URI, const xmlChar * base)
+{
+ xmlChar *val;
- return val;
+ xmlBuildRelativeURISafe(URI, base, &val);
+ return(val);
}
/**
* xmlCanonicPath:
* @path: the resource locator in a filesystem notation
*
- * Constructs a canonic path from the specified path.
+ * Prepares a path.
*
- * Returns a new canonic path, or a duplicate of the path parameter if the
- * construction fails. The caller is responsible for freeing the memory occupied
+ * If the path contains the substring "://", it is considered a
+ * Legacy Extended IRI. Characters which aren't allowed in URIs are
+ * escaped.
+ *
+ * Otherwise, the path is considered a filesystem path which is
+ * copied without modification.
+ *
+ * The caller is responsible for freeing the memory occupied
* by the returned string. If there is insufficient memory available, or the
* argument is NULL, the function returns NULL.
+ *
+ * Returns the escaped path.
*/
-#define IS_WINDOWS_PATH(p) \
- ((p != NULL) && \
- (((p[0] >= 'a') && (p[0] <= 'z')) || \
- ((p[0] >= 'A') && (p[0] <= 'Z'))) && \
- (p[1] == ':') && ((p[2] == '/') || (p[2] == '\\')))
xmlChar *
xmlCanonicPath(const xmlChar *path)
{
-/*
- * For Windows implementations, additional work needs to be done to
- * replace backslashes in pathnames with "forward slashes"
- */
-#if defined(_WIN32)
- int len = 0;
- char *p = NULL;
-#endif
- xmlURIPtr uri;
xmlChar *ret;
- const xmlChar *absuri;
if (path == NULL)
return(NULL);
-#if defined(_WIN32)
- /*
- * We must not change the backslashes to slashes if the the path
- * starts with \\?\
- * Those paths can be up to 32k characters long.
- * Was added specifically for OpenOffice, those paths can't be converted
- * to URIs anyway.
- */
- if ((path[0] == '\\') && (path[1] == '\\') && (path[2] == '?') &&
- (path[3] == '\\') )
- return xmlStrdup((const xmlChar *) path);
-#endif
-
- /* sanitize filename starting with // so it can be used as URI */
- if ((path[0] == '/') && (path[1] == '/') && (path[2] != '/'))
- path++;
-
- if ((uri = xmlParseURI((const char *) path)) != NULL) {
- xmlFreeURI(uri);
- return xmlStrdup(path);
- }
-
/* Check if this is an "absolute uri" */
- absuri = xmlStrstr(path, BAD_CAST "://");
- if (absuri != NULL) {
- int l, j;
- unsigned char c;
- xmlChar *escURI;
-
- /*
- * this looks like an URI where some parts have not been
- * escaped leading to a parsing problem. Check that the first
- * part matches a protocol.
- */
- l = absuri - path;
- /* Bypass if first part (part before the '://') is > 20 chars */
- if ((l <= 0) || (l > 20))
- goto path_processing;
- /* Bypass if any non-alpha characters are present in first part */
- for (j = 0;j < l;j++) {
- c = path[j];
- if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))))
- goto path_processing;
- }
-
- /* Escape all except the characters specified in the supplied path */
- escURI = xmlURIEscapeStr(path, BAD_CAST ":/?_.#&;=");
- if (escURI != NULL) {
- /* Try parsing the escaped path */
- uri = xmlParseURI((const char *) escURI);
- /* If successful, return the escaped string */
- if (uri != NULL) {
- xmlFreeURI(uri);
- return escURI;
- }
- xmlFree(escURI);
- }
- }
-
-path_processing:
-/* For Windows implementations, replace backslashes with 'forward slashes' */
-#if defined(_WIN32)
- /*
- * Create a URI structure
- */
- uri = xmlCreateURI();
- if (uri == NULL) { /* Guard against 'out of memory' */
- return(NULL);
- }
-
- len = xmlStrlen(path);
- if ((len > 2) && IS_WINDOWS_PATH(path)) {
- /* make the scheme 'file' */
- uri->scheme = (char *) xmlStrdup(BAD_CAST "file");
- /* allocate space for leading '/' + path + string terminator */
- uri->path = xmlMallocAtomic(len + 2);
- if (uri->path == NULL) {
- xmlFreeURI(uri); /* Guard against 'out of memory' */
- return(NULL);
- }
- /* Put in leading '/' plus path */
- uri->path[0] = '/';
- p = uri->path + 1;
- strncpy(p, (char *) path, len + 1);
- } else {
- uri->path = (char *) xmlStrdup(path);
- if (uri->path == NULL) {
- xmlFreeURI(uri);
- return(NULL);
- }
- p = uri->path;
- }
- /* Now change all occurrences of '\' to '/' */
- while (*p != '\0') {
- if (*p == '\\')
- *p = '/';
- p++;
- }
-
- if (uri->scheme == NULL) {
- ret = xmlStrdup((const xmlChar *) uri->path);
+ if (xmlStrstr(path, BAD_CAST "://") != NULL) {
+ /*
+ * Escape all characters except reserved, unreserved and the
+ * percent sign.
+ *
+ * xmlURIEscapeStr already keeps unreserved characters, so we
+ * pass gen-delims, sub-delims and "%" to ignore.
+ */
+ ret = xmlURIEscapeStr(path, BAD_CAST ":/?#[]@!$&()*+,;='%");
} else {
- ret = xmlSaveUri(uri);
+ ret = xmlStrdup((const xmlChar *) path);
}
- xmlFreeURI(uri);
-#else
- ret = xmlStrdup((const xmlChar *) path);
-#endif
return(ret);
}
@@ -2534,41 +2701,5 @@ xmlCanonicPath(const xmlChar *path)
xmlChar *
xmlPathToURI(const xmlChar *path)
{
- xmlURIPtr uri;
- xmlURI temp;
- xmlChar *ret, *cal;
-
- if (path == NULL)
- return(NULL);
-
- if ((uri = xmlParseURI((const char *) path)) != NULL) {
- xmlFreeURI(uri);
- return xmlStrdup(path);
- }
- cal = xmlCanonicPath(path);
- if (cal == NULL)
- return(NULL);
-#if defined(_WIN32)
- /* xmlCanonicPath can return an URI on Windows (is that the intended behaviour?)
- If 'cal' is a valid URI already then we are done here, as continuing would make
- it invalid. */
- if ((uri = xmlParseURI((const char *) cal)) != NULL) {
- xmlFreeURI(uri);
- return cal;
- }
- /* 'cal' can contain a relative path with backslashes. If that is processed
- by xmlSaveURI, they will be escaped and the external entity loader machinery
- will fail. So convert them to slashes. Misuse 'ret' for walking. */
- ret = cal;
- while (*ret != '\0') {
- if (*ret == '\\')
- *ret = '/';
- ret++;
- }
-#endif
- memset(&temp, 0, sizeof(temp));
- temp.path = (char *) cal;
- ret = xmlSaveUri(&temp);
- xmlFree(cal);
- return(ret);
+ return(xmlCanonicPath(path));
}
diff --git a/valid.c b/valid.c
index 76d657d..1b711e6 100644
--- a/valid.c
+++ b/valid.c
@@ -21,18 +21,16 @@
#include
#include
#include
+#include
#include "private/error.h"
#include "private/parser.h"
+#include "private/regexp.h"
+#include "private/save.h"
+#include "private/tree.h"
static xmlElementPtr
-xmlGetDtdElementDesc2(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
- int create);
-
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
+xmlGetDtdElementDesc2(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name);
#ifdef LIBXML_VALID_ENABLED
static int
@@ -53,31 +51,56 @@ xmlValidateAttributeValueInternal(xmlDocPtr doc, xmlAttributeType type,
* Handle an out of memory error
*/
static void
-xmlVErrMemory(xmlValidCtxtPtr ctxt, const char *extra)
+xmlVErrMemory(xmlValidCtxtPtr ctxt)
{
- xmlGenericErrorFunc channel = NULL;
+ if (ctxt != NULL) {
+ if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
+ xmlCtxtErrMemory(ctxt->userData);
+ } else {
+ xmlRaiseMemoryError(NULL, ctxt->error, ctxt->userData,
+ XML_FROM_VALID, NULL);
+ }
+ } else {
+ xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_VALID, NULL);
+ }
+}
+
+static void
+xmlDoErrValid(xmlValidCtxtPtr ctxt, xmlNodePtr node,
+ xmlParserErrors code, int level,
+ const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
+ int int1,
+ const char *msg, ...) {
xmlParserCtxtPtr pctxt = NULL;
- void *data = NULL;
+ va_list ap;
- if (ctxt != NULL) {
- channel = ctxt->error;
- data = ctxt->userData;
- /* Look up flag to detect if it is part of a parsing
- context */
- if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
- pctxt = ctxt->userData;
- }
+ if (ctxt == NULL)
+ return;
+ if (ctxt->flags & XML_VCTXT_USE_PCTXT)
+ pctxt = ctxt->userData;
+
+ va_start(ap, msg);
+ if (pctxt != NULL) {
+ xmlCtxtVErr(pctxt, node, XML_FROM_VALID, code, level,
+ str1, str2, str3, int1, msg, ap);
+ } else {
+ xmlGenericErrorFunc channel = NULL;
+ void *data = NULL;
+ int res;
+
+ if (ctxt != NULL) {
+ channel = ctxt->error;
+ data = ctxt->userData;
+ }
+ res = xmlVRaiseError(NULL, channel, data, NULL, node,
+ XML_FROM_VALID, code, level, NULL, 0,
+ (const char *) str1, (const char *) str2,
+ (const char *) str2, int1, 0,
+ msg, ap);
+ if (res < 0)
+ xmlVErrMemory(ctxt);
}
- if (extra)
- __xmlRaiseError(NULL, channel, data,
- pctxt, NULL, XML_FROM_VALID, XML_ERR_NO_MEMORY,
- XML_ERR_FATAL, NULL, 0, extra, NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
- else
- __xmlRaiseError(NULL, channel, data,
- pctxt, NULL, XML_FROM_VALID, XML_ERR_NO_MEMORY,
- XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0,
- "Memory allocation failed\n");
+ va_end(ap);
}
/**
@@ -92,29 +115,8 @@ static void LIBXML_ATTR_FORMAT(3,0)
xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error,
const char *msg, const char *extra)
{
- xmlGenericErrorFunc channel = NULL;
- xmlParserCtxtPtr pctxt = NULL;
- void *data = NULL;
-
- if (ctxt != NULL) {
- channel = ctxt->error;
- data = ctxt->userData;
- /* Look up flag to detect if it is part of a parsing
- context */
- if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
- pctxt = ctxt->userData;
- }
- }
- if (extra)
- __xmlRaiseError(NULL, channel, data,
- pctxt, NULL, XML_FROM_VALID, error,
- XML_ERR_ERROR, NULL, 0, extra, NULL, NULL, 0, 0,
- msg, extra);
- else
- __xmlRaiseError(NULL, channel, data,
- pctxt, NULL, XML_FROM_VALID, error,
- XML_ERR_ERROR, NULL, 0, NULL, NULL, NULL, 0, 0,
- "%s", msg);
+ xmlDoErrValid(ctxt, NULL, error, XML_ERR_ERROR, (const xmlChar *) extra,
+ NULL, NULL, 0, msg, extra);
}
#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
@@ -135,25 +137,8 @@ xmlErrValidNode(xmlValidCtxtPtr ctxt,
const char *msg, const xmlChar * str1,
const xmlChar * str2, const xmlChar * str3)
{
- xmlStructuredErrorFunc schannel = NULL;
- xmlGenericErrorFunc channel = NULL;
- xmlParserCtxtPtr pctxt = NULL;
- void *data = NULL;
-
- if (ctxt != NULL) {
- channel = ctxt->error;
- data = ctxt->userData;
- /* Look up flag to detect if it is part of a parsing
- context */
- if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
- pctxt = ctxt->userData;
- }
- }
- __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,
- XML_ERR_ERROR, NULL, 0,
- (const char *) str1,
- (const char *) str2,
- (const char *) str3, 0, 0, msg, str1, str2, str3);
+ xmlDoErrValid(ctxt, node, error, XML_ERR_ERROR, str1, str2, str3, 0,
+ msg, str1, str2, str3);
}
#endif /* LIBXML_VALID_ENABLED or LIBXML_SCHEMAS_ENABLED */
@@ -175,25 +160,8 @@ xmlErrValidNodeNr(xmlValidCtxtPtr ctxt,
const char *msg, const xmlChar * str1,
int int2, const xmlChar * str3)
{
- xmlStructuredErrorFunc schannel = NULL;
- xmlGenericErrorFunc channel = NULL;
- xmlParserCtxtPtr pctxt = NULL;
- void *data = NULL;
-
- if (ctxt != NULL) {
- channel = ctxt->error;
- data = ctxt->userData;
- /* Look up flag to detect if it is part of a parsing
- context */
- if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
- pctxt = ctxt->userData;
- }
- }
- __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,
- XML_ERR_ERROR, NULL, 0,
- (const char *) str1,
- (const char *) str3,
- NULL, int2, 0, msg, str1, int2, str3);
+ xmlDoErrValid(ctxt, node, error, XML_ERR_ERROR, str1, str3, NULL, int2,
+ msg, str1, int2, str3);
}
/**
@@ -213,25 +181,8 @@ xmlErrValidWarning(xmlValidCtxtPtr ctxt,
const char *msg, const xmlChar * str1,
const xmlChar * str2, const xmlChar * str3)
{
- xmlStructuredErrorFunc schannel = NULL;
- xmlGenericErrorFunc channel = NULL;
- xmlParserCtxtPtr pctxt = NULL;
- void *data = NULL;
-
- if (ctxt != NULL) {
- channel = ctxt->warning;
- data = ctxt->userData;
- /* Look up flag to detect if it is part of a parsing
- context */
- if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
- pctxt = ctxt->userData;
- }
- }
- __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,
- XML_ERR_WARNING, NULL, 0,
- (const char *) str1,
- (const char *) str2,
- (const char *) str3, 0, 0, msg, str1, str2, str3);
+ xmlDoErrValid(ctxt, node, error, XML_ERR_WARNING, str1, str2, str3, 0,
+ msg, str1, str2, str3);
}
@@ -260,7 +211,7 @@ vstateVPush(xmlValidCtxtPtr ctxt, xmlElementPtr elemDecl, xmlNodePtr node) {
ctxt->vstateTab = (xmlValidState *) xmlMalloc(ctxt->vstateMax *
sizeof(ctxt->vstateTab[0]));
if (ctxt->vstateTab == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
+ xmlVErrMemory(ctxt);
return(-1);
}
}
@@ -271,7 +222,7 @@ vstateVPush(xmlValidCtxtPtr ctxt, xmlElementPtr elemDecl, xmlNodePtr node) {
tmp = (xmlValidState *) xmlRealloc(ctxt->vstateTab,
2 * ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
if (tmp == NULL) {
- xmlVErrMemory(ctxt, "realloc failed");
+ xmlVErrMemory(ctxt);
return(-1);
}
ctxt->vstateMax *= 2;
@@ -286,6 +237,10 @@ vstateVPush(xmlValidCtxtPtr ctxt, xmlElementPtr elemDecl, xmlNodePtr node) {
if (elemDecl->contModel != NULL) {
ctxt->vstateTab[ctxt->vstateNr].exec =
xmlRegNewExecCtxt(elemDecl->contModel, NULL, NULL);
+ if (ctxt->vstateTab[ctxt->vstateNr].exec == NULL) {
+ xmlVErrMemory(ctxt);
+ return(-1);
+ }
} else {
ctxt->vstateTab[ctxt->vstateNr].exec = NULL;
xmlErrValidNode(ctxt, (xmlNodePtr) elemDecl,
@@ -367,7 +322,7 @@ vstateVPush(xmlValidCtxtPtr ctxt, xmlElementContentPtr cont,
ctxt->vstateTab = (xmlValidState *) xmlMalloc(
ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
if (ctxt->vstateTab == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
+ xmlVErrMemory(ctxt);
return(-1);
}
}
@@ -377,7 +332,7 @@ vstateVPush(xmlValidCtxtPtr ctxt, xmlElementContentPtr cont,
tmp = (xmlValidState *) xmlRealloc(ctxt->vstateTab,
2 * ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
if (tmp == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
+ xmlVErrMemory(ctxt);
return(-1);
}
ctxt->vstateMax *= 2;
@@ -425,7 +380,7 @@ nodeVPush(xmlValidCtxtPtr ctxt, xmlNodePtr value)
(xmlNodePtr *) xmlMalloc(ctxt->nodeMax *
sizeof(ctxt->nodeTab[0]));
if (ctxt->nodeTab == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
+ xmlVErrMemory(ctxt);
ctxt->nodeMax = 0;
return (0);
}
@@ -435,7 +390,7 @@ nodeVPush(xmlValidCtxtPtr ctxt, xmlNodePtr value)
tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
ctxt->nodeMax * 2 * sizeof(ctxt->nodeTab[0]));
if (tmp == NULL) {
- xmlVErrMemory(ctxt, "realloc failed");
+ xmlVErrMemory(ctxt);
return (0);
}
ctxt->nodeMax *= 2;
@@ -512,7 +467,7 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
fullname = xmlBuildQName(content->name, content->prefix, fn, 50);
if (fullname == NULL) {
- xmlVErrMemory(ctxt, "Building content model");
+ xmlVErrMemory(ctxt);
return(0);
}
@@ -557,11 +512,13 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
oldstate = ctxt->state;
}
do {
- xmlValidBuildAContentModel(content->c1, ctxt, name);
+ if (xmlValidBuildAContentModel(content->c1, ctxt, name) == 0)
+ return(0);
content = content->c2;
} while ((content->type == XML_ELEMENT_CONTENT_SEQ) &&
(content->ocur == XML_ELEMENT_CONTENT_ONCE));
- xmlValidBuildAContentModel(content, ctxt, name);
+ if (xmlValidBuildAContentModel(content, ctxt, name) == 0)
+ return(0);
oldend = ctxt->state;
ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL);
switch (ocur) {
@@ -599,13 +556,15 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
*/
do {
ctxt->state = oldstate;
- xmlValidBuildAContentModel(content->c1, ctxt, name);
+ if (xmlValidBuildAContentModel(content->c1, ctxt, name) == 0)
+ return(0);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend);
content = content->c2;
} while ((content->type == XML_ELEMENT_CONTENT_OR) &&
(content->ocur == XML_ELEMENT_CONTENT_ONCE));
ctxt->state = oldstate;
- xmlValidBuildAContentModel(content, ctxt, name);
+ if (xmlValidBuildAContentModel(content, ctxt, name) == 0)
+ return(0);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend);
ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL);
switch (ocur) {
@@ -637,6 +596,8 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
* @ctxt: a validation context
* @elem: an element declaration node
*
+ * DEPRECATED: Internal function, don't use.
+ *
* (Re)Build the automata associated to the content model of this
* element
*
@@ -644,6 +605,7 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
*/
int
xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
+ int ret = 0;
if ((ctxt == NULL) || (elem == NULL))
return(0);
@@ -662,16 +624,18 @@ xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
ctxt->am = xmlNewAutomata();
if (ctxt->am == NULL) {
- xmlErrValidNode(ctxt, (xmlNodePtr) elem,
- XML_ERR_INTERNAL_ERROR,
- "Cannot create automata for element %s\n",
- elem->name, NULL, NULL);
+ xmlVErrMemory(ctxt);
return(0);
}
ctxt->state = xmlAutomataGetInitState(ctxt->am);
- xmlValidBuildAContentModel(elem->content, ctxt, elem->name);
+ if (xmlValidBuildAContentModel(elem->content, ctxt, elem->name) == 0)
+ goto done;
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
elem->contModel = xmlAutomataCompile(ctxt->am);
+ if (elem->contModel == NULL) {
+ xmlVErrMemory(ctxt);
+ goto done;
+ }
if (xmlRegexpIsDeterminist(elem->contModel) != 1) {
char expr[5000];
expr[0] = 0;
@@ -681,15 +645,16 @@ xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
"Content model of %s is not deterministic: %s\n",
elem->name, BAD_CAST expr, NULL);
ctxt->valid = 0;
- ctxt->state = NULL;
- xmlFreeAutomata(ctxt->am);
- ctxt->am = NULL;
- return(0);
+ goto done;
}
+
+ ret = 1;
+
+done:
ctxt->state = NULL;
xmlFreeAutomata(ctxt->am);
ctxt->am = NULL;
- return(1);
+ return(ret);
}
#endif /* LIBXML_REGEXP_ENABLED */
@@ -710,10 +675,8 @@ xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
xmlValidCtxtPtr xmlNewValidCtxt(void) {
xmlValidCtxtPtr ret;
- if ((ret = xmlMalloc(sizeof (xmlValidCtxt))) == NULL) {
- xmlVErrMemory(NULL, "malloc failed");
+ if ((ret = xmlMalloc(sizeof (xmlValidCtxt))) == NULL)
return (NULL);
- }
(void) memset(ret, 0, sizeof (xmlValidCtxt));
@@ -782,10 +745,8 @@ xmlNewDocElementContent(xmlDocPtr doc, const xmlChar *name,
return(NULL);
}
ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));
- if (ret == NULL) {
- xmlVErrMemory(NULL, "malloc failed");
+ if (ret == NULL)
return(NULL);
- }
memset(ret, 0, sizeof(xmlElementContent));
ret->type = type;
ret->ocur = XML_ELEMENT_CONTENT_ONCE;
@@ -807,9 +768,17 @@ xmlNewDocElementContent(xmlDocPtr doc, const xmlChar *name,
ret->prefix = xmlDictLookup(dict, name, l);
ret->name = xmlDictLookup(dict, tmp, -1);
}
+ if (ret->prefix == NULL)
+ goto error;
}
+ if (ret->name == NULL)
+ goto error;
}
return(ret);
+
+error:
+ xmlFreeDocElementContent(doc, ret);
+ return(NULL);
}
/**
@@ -847,10 +816,8 @@ xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
dict = doc->dict;
ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));
- if (ret == NULL) {
- xmlVErrMemory(NULL, "malloc failed");
+ if (ret == NULL)
return(NULL);
- }
memset(ret, 0, sizeof(xmlElementContent));
ret->type = cur->type;
ret->ocur = cur->ocur;
@@ -859,6 +826,8 @@ xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
ret->name = xmlDictLookup(dict, cur->name, -1);
else
ret->name = xmlStrdup(cur->name);
+ if (ret->name == NULL)
+ goto error;
}
if (cur->prefix != NULL) {
@@ -866,20 +835,22 @@ xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
ret->prefix = xmlDictLookup(dict, cur->prefix, -1);
else
ret->prefix = xmlStrdup(cur->prefix);
+ if (ret->prefix == NULL)
+ goto error;
}
- if (cur->c1 != NULL)
+ if (cur->c1 != NULL) {
ret->c1 = xmlCopyDocElementContent(doc, cur->c1);
- if (ret->c1 != NULL)
+ if (ret->c1 == NULL)
+ goto error;
ret->c1->parent = ret;
+ }
if (cur->c2 != NULL) {
prev = ret;
cur = cur->c2;
while (cur != NULL) {
tmp = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));
- if (tmp == NULL) {
- xmlVErrMemory(NULL, "malloc failed");
- return(ret);
- }
+ if (tmp == NULL)
+ goto error;
memset(tmp, 0, sizeof(xmlElementContent));
tmp->type = cur->type;
tmp->ocur = cur->ocur;
@@ -890,6 +861,8 @@ xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
tmp->name = xmlDictLookup(dict, cur->name, -1);
else
tmp->name = xmlStrdup(cur->name);
+ if (tmp->name == NULL)
+ goto error;
}
if (cur->prefix != NULL) {
@@ -897,16 +870,24 @@ xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
tmp->prefix = xmlDictLookup(dict, cur->prefix, -1);
else
tmp->prefix = xmlStrdup(cur->prefix);
+ if (tmp->prefix == NULL)
+ goto error;
}
- if (cur->c1 != NULL)
+ if (cur->c1 != NULL) {
tmp->c1 = xmlCopyDocElementContent(doc,cur->c1);
- if (tmp->c1 != NULL)
+ if (tmp->c1 == NULL)
+ goto error;
tmp->c1->parent = tmp;
+ }
prev = tmp;
cur = cur->c2;
}
}
return(ret);
+
+error:
+ xmlFreeElementContent(ret);
+ return(NULL);
}
/**
@@ -1002,105 +983,6 @@ xmlFreeElementContent(xmlElementContentPtr cur) {
}
#ifdef LIBXML_OUTPUT_ENABLED
-/**
- * xmlDumpElementOccur:
- * @buf: An XML buffer
- * @cur: An element table
- *
- * Dump the occurrence operator of an element.
- */
-static void
-xmlDumpElementOccur(xmlBufferPtr buf, xmlElementContentPtr cur) {
- switch (cur->ocur) {
- case XML_ELEMENT_CONTENT_ONCE:
- break;
- case XML_ELEMENT_CONTENT_OPT:
- xmlBufferWriteChar(buf, "?");
- break;
- case XML_ELEMENT_CONTENT_MULT:
- xmlBufferWriteChar(buf, "*");
- break;
- case XML_ELEMENT_CONTENT_PLUS:
- xmlBufferWriteChar(buf, "+");
- break;
- }
-}
-
-/**
- * xmlDumpElementContent:
- * @buf: An XML buffer
- * @content: An element table
- *
- * This will dump the content of the element table as an XML DTD definition
- */
-static void
-xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content) {
- xmlElementContentPtr cur;
-
- if (content == NULL) return;
-
- xmlBufferWriteChar(buf, "(");
- cur = content;
-
- do {
- if (cur == NULL) return;
-
- switch (cur->type) {
- case XML_ELEMENT_CONTENT_PCDATA:
- xmlBufferWriteChar(buf, "#PCDATA");
- break;
- case XML_ELEMENT_CONTENT_ELEMENT:
- if (cur->prefix != NULL) {
- xmlBufferWriteCHAR(buf, cur->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, cur->name);
- break;
- case XML_ELEMENT_CONTENT_SEQ:
- case XML_ELEMENT_CONTENT_OR:
- if ((cur != content) &&
- (cur->parent != NULL) &&
- ((cur->type != cur->parent->type) ||
- (cur->ocur != XML_ELEMENT_CONTENT_ONCE)))
- xmlBufferWriteChar(buf, "(");
- cur = cur->c1;
- continue;
- default:
- xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
- "Internal: ELEMENT cur corrupted invalid type\n",
- NULL);
- }
-
- while (cur != content) {
- xmlElementContentPtr parent = cur->parent;
-
- if (parent == NULL) return;
-
- if (((cur->type == XML_ELEMENT_CONTENT_OR) ||
- (cur->type == XML_ELEMENT_CONTENT_SEQ)) &&
- ((cur->type != parent->type) ||
- (cur->ocur != XML_ELEMENT_CONTENT_ONCE)))
- xmlBufferWriteChar(buf, ")");
- xmlDumpElementOccur(buf, cur);
-
- if (cur == parent->c1) {
- if (parent->type == XML_ELEMENT_CONTENT_SEQ)
- xmlBufferWriteChar(buf, " , ");
- else if (parent->type == XML_ELEMENT_CONTENT_OR)
- xmlBufferWriteChar(buf, " | ");
-
- cur = parent->c2;
- break;
- }
-
- cur = parent;
- }
- } while (cur != content);
-
- xmlBufferWriteChar(buf, ")");
- xmlDumpElementOccur(buf, content);
-}
-
/**
* xmlSprintfElementContent:
* @buf: an output buffer
@@ -1267,7 +1149,8 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
xmlElementPtr ret;
xmlElementTablePtr table;
xmlAttributePtr oldAttributes = NULL;
- xmlChar *ns, *uqname;
+ const xmlChar *localName;
+ xmlChar *prefix = NULL;
if (dtd == NULL) {
return(NULL);
@@ -1279,7 +1162,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
switch (type) {
case XML_ELEMENT_TYPE_EMPTY:
if (content != NULL) {
- xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
+ xmlErrValid(ctxt, XML_DTD_CONTENT_ERROR,
"xmlAddElementDecl: content != NULL for EMPTY\n",
NULL);
return(NULL);
@@ -1287,7 +1170,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
break;
case XML_ELEMENT_TYPE_ANY:
if (content != NULL) {
- xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
+ xmlErrValid(ctxt, XML_DTD_CONTENT_ERROR,
"xmlAddElementDecl: content != NULL for ANY\n",
NULL);
return(NULL);
@@ -1295,7 +1178,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
break;
case XML_ELEMENT_TYPE_MIXED:
if (content == NULL) {
- xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
+ xmlErrValid(ctxt, XML_DTD_CONTENT_ERROR,
"xmlAddElementDecl: content == NULL for MIXED\n",
NULL);
return(NULL);
@@ -1303,25 +1186,24 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
break;
case XML_ELEMENT_TYPE_ELEMENT:
if (content == NULL) {
- xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
+ xmlErrValid(ctxt, XML_DTD_CONTENT_ERROR,
"xmlAddElementDecl: content == NULL for ELEMENT\n",
NULL);
return(NULL);
}
break;
default:
- xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
- "Internal: ELEMENT decl corrupted invalid type\n",
- NULL);
+ xmlErrValid(ctxt, XML_ERR_ARGUMENT,
+ "xmlAddElementDecl: invalid type\n", NULL);
return(NULL);
}
/*
* check if name is a QName
*/
- uqname = xmlSplitQName2(name, &ns);
- if (uqname != NULL)
- name = uqname;
+ localName = xmlSplitQName4(name, &prefix);
+ if (localName == NULL)
+ goto mem_error;
/*
* Create the Element table if needed.
@@ -1333,28 +1215,22 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
if (dtd->doc != NULL)
dict = dtd->doc->dict;
table = xmlHashCreateDict(0, dict);
+ if (table == NULL)
+ goto mem_error;
dtd->elements = (void *) table;
}
- if (table == NULL) {
- xmlVErrMemory(ctxt,
- "xmlAddElementDecl: Table creation failed!\n");
- if (uqname != NULL)
- xmlFree(uqname);
- if (ns != NULL)
- xmlFree(ns);
- return(NULL);
- }
/*
* lookup old attributes inserted on an undefined element in the
* internal subset.
*/
if ((dtd->doc != NULL) && (dtd->doc->intSubset != NULL)) {
- ret = xmlHashLookup2(dtd->doc->intSubset->elements, name, ns);
+ ret = xmlHashLookup2(dtd->doc->intSubset->elements, localName, prefix);
if ((ret != NULL) && (ret->etype == XML_ELEMENT_TYPE_UNDEFINED)) {
oldAttributes = ret->attributes;
ret->attributes = NULL;
- xmlHashRemoveEntry2(dtd->doc->intSubset->elements, name, ns, NULL);
+ xmlHashRemoveEntry2(dtd->doc->intSubset->elements, localName, prefix,
+ NULL);
xmlFreeElement(ret);
}
}
@@ -1363,7 +1239,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
* The element may already be present if one of its attribute
* was registered first
*/
- ret = xmlHashLookup2(table, name, ns);
+ ret = xmlHashLookup2(table, localName, prefix);
if (ret != NULL) {
if (ret->etype != XML_ELEMENT_TYPE_UNDEFINED) {
#ifdef LIBXML_VALID_ENABLED
@@ -1374,61 +1250,42 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
"Redefinition of element %s\n",
name, NULL, NULL);
#endif /* LIBXML_VALID_ENABLED */
- if (uqname != NULL)
- xmlFree(uqname);
- if (ns != NULL)
- xmlFree(ns);
+ if (prefix != NULL)
+ xmlFree(prefix);
return(NULL);
}
- if (ns != NULL) {
- xmlFree(ns);
- ns = NULL;
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ prefix = NULL;
}
} else {
+ int res;
+
ret = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
- if (ret == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
- if (uqname != NULL)
- xmlFree(uqname);
- if (ns != NULL)
- xmlFree(ns);
- return(NULL);
- }
+ if (ret == NULL)
+ goto mem_error;
memset(ret, 0, sizeof(xmlElement));
ret->type = XML_ELEMENT_DECL;
/*
* fill the structure.
*/
- ret->name = xmlStrdup(name);
+ ret->name = xmlStrdup(localName);
if (ret->name == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
- if (uqname != NULL)
- xmlFree(uqname);
- if (ns != NULL)
- xmlFree(ns);
xmlFree(ret);
- return(NULL);
+ goto mem_error;
}
- ret->prefix = ns;
+ ret->prefix = prefix;
+ prefix = NULL;
/*
* Validity Check:
* Insertion must not fail
*/
- if (xmlHashAddEntry2(table, name, ns, ret)) {
-#ifdef LIBXML_VALID_ENABLED
- /*
- * The element is already defined in this DTD.
- */
- xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_ELEM_REDEFINED,
- "Redefinition of element %s\n",
- name, NULL, NULL);
-#endif /* LIBXML_VALID_ENABLED */
+ res = xmlHashAdd2(table, localName, ret->prefix, ret);
+ if (res <= 0) {
xmlFreeElement(ret);
- if (uqname != NULL)
- xmlFree(uqname);
- return(NULL);
+ goto mem_error;
}
/*
* For new element, may have attributes from earlier
@@ -1446,12 +1303,15 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
* and flag it by setting a special parent value
* so the parser doesn't unallocate it.
*/
- if ((ctxt != NULL) && (ctxt->flags & XML_VCTXT_USE_PCTXT)) {
- ret->content = content;
- if (content != NULL)
- content->parent = (xmlElementContentPtr) 1;
- } else {
- ret->content = xmlCopyDocElementContent(dtd->doc, content);
+ if (content != NULL) {
+ if ((ctxt != NULL) && (ctxt->flags & XML_VCTXT_USE_PCTXT)) {
+ ret->content = content;
+ content->parent = (xmlElementContentPtr) 1;
+ } else if (content != NULL){
+ ret->content = xmlCopyDocElementContent(dtd->doc, content);
+ if (ret->content == NULL)
+ goto mem_error;
+ }
}
/*
@@ -1466,9 +1326,15 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
ret->prev = dtd->last;
dtd->last = (xmlNodePtr) ret;
}
- if (uqname != NULL)
- xmlFree(uqname);
+ if (prefix != NULL)
+ xmlFree(prefix);
return(ret);
+
+mem_error:
+ xmlVErrMemory(ctxt);
+ if (prefix != NULL)
+ xmlFree(prefix);
+ return(NULL);
}
static void
@@ -1502,25 +1368,33 @@ xmlCopyElement(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
xmlElementPtr cur;
cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
- if (cur == NULL) {
- xmlVErrMemory(NULL, "malloc failed");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlElement));
cur->type = XML_ELEMENT_DECL;
cur->etype = elem->etype;
- if (elem->name != NULL)
+ if (elem->name != NULL) {
cur->name = xmlStrdup(elem->name);
- else
- cur->name = NULL;
- if (elem->prefix != NULL)
+ if (cur->name == NULL)
+ goto error;
+ }
+ if (elem->prefix != NULL) {
cur->prefix = xmlStrdup(elem->prefix);
- else
- cur->prefix = NULL;
- cur->content = xmlCopyElementContent(elem->content);
+ if (cur->prefix == NULL)
+ goto error;
+ }
+ if (elem->content != NULL) {
+ cur->content = xmlCopyElementContent(elem->content);
+ if (cur->content == NULL)
+ goto error;
+ }
/* TODO : rebuild the attribute list on the copy */
cur->attributes = NULL;
return(cur);
+
+error:
+ xmlFreeElement(cur);
+ return(NULL);
}
/**
@@ -1533,7 +1407,7 @@ xmlCopyElement(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
*/
xmlElementTablePtr
xmlCopyElementTable(xmlElementTablePtr table) {
- return((xmlElementTablePtr) xmlHashCopy(table, xmlCopyElement));
+ return(xmlHashCopySafe(table, xmlCopyElement, xmlFreeElementTableEntry));
}
#endif /* LIBXML_TREE_ENABLED */
@@ -1543,59 +1417,22 @@ xmlCopyElementTable(xmlElementTablePtr table) {
* @buf: the XML buffer output
* @elem: An element table
*
+ * DEPRECATED: Use xmlSaveTree.
+ *
* This will dump the content of the element declaration as an XML
* DTD definition
*/
void
xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
+ xmlSaveCtxtPtr save;
+
if ((buf == NULL) || (elem == NULL))
return;
- switch (elem->etype) {
- case XML_ELEMENT_TYPE_EMPTY:
- xmlBufferWriteChar(buf, "prefix != NULL) {
- xmlBufferWriteCHAR(buf, elem->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, elem->name);
- xmlBufferWriteChar(buf, " EMPTY>\n");
- break;
- case XML_ELEMENT_TYPE_ANY:
- xmlBufferWriteChar(buf, "prefix != NULL) {
- xmlBufferWriteCHAR(buf, elem->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, elem->name);
- xmlBufferWriteChar(buf, " ANY>\n");
- break;
- case XML_ELEMENT_TYPE_MIXED:
- xmlBufferWriteChar(buf, "prefix != NULL) {
- xmlBufferWriteCHAR(buf, elem->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, elem->name);
- xmlBufferWriteChar(buf, " ");
- xmlDumpElementContent(buf, elem->content);
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_ELEMENT_TYPE_ELEMENT:
- xmlBufferWriteChar(buf, "prefix != NULL) {
- xmlBufferWriteCHAR(buf, elem->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, elem->name);
- xmlBufferWriteChar(buf, " ");
- xmlDumpElementContent(buf, elem->content);
- xmlBufferWriteChar(buf, ">\n");
- break;
- default:
- xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
- "Internal: ELEMENT struct corrupted invalid type\n",
- NULL);
- }
+
+ save = xmlSaveToBuffer(buf, NULL, 0);
+ xmlSaveTree(save, (xmlNodePtr) elem);
+ if (xmlSaveFinish(save) != XML_ERR_OK)
+ xmlFree(xmlBufferDetach(buf));
}
/**
@@ -1607,9 +1444,9 @@ xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
* the arguments.
*/
static void
-xmlDumpElementDeclScan(void *elem, void *buf,
+xmlDumpElementDeclScan(void *elem, void *save,
const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlDumpElementDecl((xmlBufferPtr) buf, (xmlElementPtr) elem);
+ xmlSaveTree(save, elem);
}
/**
@@ -1617,13 +1454,21 @@ xmlDumpElementDeclScan(void *elem, void *buf,
* @buf: the XML buffer output
* @table: An element table
*
+ * DEPRECATED: Don't use.
+ *
* This will dump the content of the element table as an XML DTD definition
*/
void
xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
+ xmlSaveCtxtPtr save;
+
if ((buf == NULL) || (table == NULL))
return;
- xmlHashScan(table, xmlDumpElementDeclScan, buf);
+
+ save = xmlSaveToBuffer(buf, NULL, 0);
+ xmlHashScan(table, xmlDumpElementDeclScan, save);
+ if (xmlSaveFinish(save) != XML_ERR_OK)
+ xmlFree(xmlBufferDetach(buf));
}
#endif /* LIBXML_OUTPUT_ENABLED */
@@ -1641,14 +1486,18 @@ xmlCreateEnumeration(const xmlChar *name) {
xmlEnumerationPtr ret;
ret = (xmlEnumerationPtr) xmlMalloc(sizeof(xmlEnumeration));
- if (ret == NULL) {
- xmlVErrMemory(NULL, "malloc failed");
+ if (ret == NULL)
return(NULL);
- }
memset(ret, 0, sizeof(xmlEnumeration));
- if (name != NULL)
+ if (name != NULL) {
ret->name = xmlStrdup(name);
+ if (ret->name == NULL) {
+ xmlFree(ret);
+ return(NULL);
+ }
+ }
+
return(ret);
}
@@ -1660,12 +1509,14 @@ xmlCreateEnumeration(const xmlChar *name) {
*/
void
xmlFreeEnumeration(xmlEnumerationPtr cur) {
- if (cur == NULL) return;
+ while (cur != NULL) {
+ xmlEnumerationPtr next = cur->next;
- if (cur->next != NULL) xmlFreeEnumeration(cur->next);
+ xmlFree((xmlChar *) cur->name);
+ xmlFree(cur);
- if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
- xmlFree(cur);
+ cur = next;
+ }
}
#ifdef LIBXML_TREE_ENABLED
@@ -1680,41 +1531,30 @@ xmlFreeEnumeration(xmlEnumerationPtr cur) {
*/
xmlEnumerationPtr
xmlCopyEnumeration(xmlEnumerationPtr cur) {
- xmlEnumerationPtr ret;
-
- if (cur == NULL) return(NULL);
- ret = xmlCreateEnumeration((xmlChar *) cur->name);
- if (ret == NULL) return(NULL);
+ xmlEnumerationPtr ret = NULL;
+ xmlEnumerationPtr last = NULL;
- if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
- else ret->next = NULL;
+ while (cur != NULL) {
+ xmlEnumerationPtr copy = xmlCreateEnumeration(cur->name);
- return(ret);
-}
-#endif /* LIBXML_TREE_ENABLED */
+ if (copy == NULL) {
+ xmlFreeEnumeration(ret);
+ return(NULL);
+ }
-#ifdef LIBXML_OUTPUT_ENABLED
-/**
- * xmlDumpEnumeration:
- * @buf: the XML buffer output
- * @enum: An enumeration
- *
- * This will dump the content of the enumeration
- */
-static void
-xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
- if ((buf == NULL) || (cur == NULL))
- return;
+ if (ret == NULL) {
+ ret = last = copy;
+ } else {
+ last->next = copy;
+ last = copy;
+ }
- xmlBufferWriteCHAR(buf, cur->name);
- if (cur->next == NULL)
- xmlBufferWriteChar(buf, ")");
- else {
- xmlBufferWriteChar(buf, " | ");
- xmlDumpEnumeration(buf, cur->next);
+ cur = cur->next;
}
+
+ return(ret);
}
-#endif /* LIBXML_OUTPUT_ENABLED */
+#endif /* LIBXML_TREE_ENABLED */
#ifdef LIBXML_VALID_ENABLED
/**
@@ -1814,10 +1654,11 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
const xmlChar *name, const xmlChar *ns,
xmlAttributeType type, xmlAttributeDefault def,
const xmlChar *defaultValue, xmlEnumerationPtr tree) {
- xmlAttributePtr ret;
+ xmlAttributePtr ret = NULL;
xmlAttributeTablePtr table;
xmlElementPtr elemDef;
xmlDictPtr dict = NULL;
+ int res;
if (dtd == NULL) {
xmlFreeEnumeration(tree);
@@ -1860,9 +1701,8 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
case XML_ATTRIBUTE_NOTATION:
break;
default:
- xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
- "Internal: ATTRIBUTE struct corrupted invalid type\n",
- NULL);
+ xmlErrValid(ctxt, XML_ERR_ARGUMENT,
+ "xmlAddAttributeDecl: invalid type\n", NULL);
xmlFreeEnumeration(tree);
return(NULL);
}
@@ -1899,20 +1739,12 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
table = xmlHashCreateDict(0, dict);
dtd->attributes = (void *) table;
}
- if (table == NULL) {
- xmlVErrMemory(ctxt,
- "xmlAddAttributeDecl: Table creation failed!\n");
- xmlFreeEnumeration(tree);
- return(NULL);
- }
-
+ if (table == NULL)
+ goto mem_error;
ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
- if (ret == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
- xmlFreeEnumeration(tree);
- return(NULL);
- }
+ if (ret == NULL)
+ goto mem_error;
memset(ret, 0, sizeof(xmlAttribute));
ret->type = XML_ATTRIBUTE_DECL;
@@ -1928,34 +1760,53 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
ret->doc = dtd->doc;
if (dict) {
ret->name = xmlDictLookup(dict, name, -1);
- ret->prefix = xmlDictLookup(dict, ns, -1);
ret->elem = xmlDictLookup(dict, elem, -1);
} else {
ret->name = xmlStrdup(name);
- ret->prefix = xmlStrdup(ns);
ret->elem = xmlStrdup(elem);
}
+ if ((ret->name == NULL) || (ret->elem == NULL))
+ goto mem_error;
+ if (ns != NULL) {
+ if (dict)
+ ret->prefix = xmlDictLookup(dict, ns, -1);
+ else
+ ret->prefix = xmlStrdup(ns);
+ if (ret->prefix == NULL)
+ goto mem_error;
+ }
ret->def = def;
ret->tree = tree;
+ tree = NULL;
if (defaultValue != NULL) {
if (dict)
ret->defaultValue = xmlDictLookup(dict, defaultValue, -1);
else
ret->defaultValue = xmlStrdup(defaultValue);
+ if (ret->defaultValue == NULL)
+ goto mem_error;
}
+ elemDef = xmlGetDtdElementDesc2(ctxt, dtd, elem);
+ if (elemDef == NULL)
+ goto mem_error;
+
/*
* Validity Check:
* Search the DTD for previous declarations of the ATTLIST
*/
- if (xmlHashAddEntry3(table, ret->name, ret->prefix, ret->elem, ret) < 0) {
+ res = xmlHashAdd3(table, ret->name, ret->prefix, ret->elem, ret);
+ if (res <= 0) {
+ if (res < 0)
+ goto mem_error;
#ifdef LIBXML_VALID_ENABLED
- /*
- * The attribute is already defined in this DTD.
- */
- xmlErrValidWarning(ctxt, (xmlNodePtr) dtd, XML_DTD_ATTRIBUTE_REDEFINED,
- "Attribute %s of element %s: already defined\n",
- name, elem, NULL);
+ /*
+ * The attribute is already defined in this DTD.
+ */
+ xmlErrValidWarning(ctxt, (xmlNodePtr) dtd,
+ XML_DTD_ATTRIBUTE_REDEFINED,
+ "Attribute %s of element %s: already defined\n",
+ name, elem, NULL);
#endif /* LIBXML_VALID_ENABLED */
xmlFreeAttribute(ret);
return(NULL);
@@ -1965,48 +1816,44 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
* Validity Check:
* Multiple ID per element
*/
- elemDef = xmlGetDtdElementDesc2(ctxt, dtd, elem, 1);
- if (elemDef != NULL) {
-
#ifdef LIBXML_VALID_ENABLED
- if ((type == XML_ATTRIBUTE_ID) &&
- (xmlScanIDAttributeDecl(NULL, elemDef, 1) != 0)) {
- xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_MULTIPLE_ID,
- "Element %s has too may ID attributes defined : %s\n",
- elem, name, NULL);
- if (ctxt != NULL)
- ctxt->valid = 0;
- }
+ if ((type == XML_ATTRIBUTE_ID) &&
+ (xmlScanIDAttributeDecl(ctxt, elemDef, 1) != 0)) {
+ xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_MULTIPLE_ID,
+ "Element %s has too may ID attributes defined : %s\n",
+ elem, name, NULL);
+ if (ctxt != NULL)
+ ctxt->valid = 0;
+ }
#endif /* LIBXML_VALID_ENABLED */
- /*
- * Insert namespace default def first they need to be
- * processed first.
- */
- if ((xmlStrEqual(ret->name, BAD_CAST "xmlns")) ||
- ((ret->prefix != NULL &&
- (xmlStrEqual(ret->prefix, BAD_CAST "xmlns"))))) {
- ret->nexth = elemDef->attributes;
- elemDef->attributes = ret;
- } else {
- xmlAttributePtr tmp = elemDef->attributes;
+ /*
+ * Insert namespace default def first they need to be
+ * processed first.
+ */
+ if ((xmlStrEqual(ret->name, BAD_CAST "xmlns")) ||
+ ((ret->prefix != NULL &&
+ (xmlStrEqual(ret->prefix, BAD_CAST "xmlns"))))) {
+ ret->nexth = elemDef->attributes;
+ elemDef->attributes = ret;
+ } else {
+ xmlAttributePtr tmp = elemDef->attributes;
- while ((tmp != NULL) &&
- ((xmlStrEqual(tmp->name, BAD_CAST "xmlns")) ||
- ((ret->prefix != NULL &&
- (xmlStrEqual(ret->prefix, BAD_CAST "xmlns")))))) {
- if (tmp->nexth == NULL)
- break;
- tmp = tmp->nexth;
- }
- if (tmp != NULL) {
- ret->nexth = tmp->nexth;
- tmp->nexth = ret;
- } else {
- ret->nexth = elemDef->attributes;
- elemDef->attributes = ret;
- }
- }
+ while ((tmp != NULL) &&
+ ((xmlStrEqual(tmp->name, BAD_CAST "xmlns")) ||
+ ((ret->prefix != NULL &&
+ (xmlStrEqual(ret->prefix, BAD_CAST "xmlns")))))) {
+ if (tmp->nexth == NULL)
+ break;
+ tmp = tmp->nexth;
+ }
+ if (tmp != NULL) {
+ ret->nexth = tmp->nexth;
+ tmp->nexth = ret;
+ } else {
+ ret->nexth = elemDef->attributes;
+ elemDef->attributes = ret;
+ }
}
/*
@@ -2021,6 +1868,12 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
dtd->last = (xmlNodePtr) ret;
}
return(ret);
+
+mem_error:
+ xmlVErrMemory(ctxt);
+ xmlFreeEnumeration(tree);
+ xmlFreeAttribute(ret);
+ return(NULL);
}
static void
@@ -2054,24 +1907,42 @@ xmlCopyAttribute(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
xmlAttributePtr cur;
cur = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
- if (cur == NULL) {
- xmlVErrMemory(NULL, "malloc failed");
+ if (cur == NULL)
return(NULL);
- }
memset(cur, 0, sizeof(xmlAttribute));
cur->type = XML_ATTRIBUTE_DECL;
cur->atype = attr->atype;
cur->def = attr->def;
- cur->tree = xmlCopyEnumeration(attr->tree);
- if (attr->elem != NULL)
+ if (attr->tree != NULL) {
+ cur->tree = xmlCopyEnumeration(attr->tree);
+ if (cur->tree == NULL)
+ goto error;
+ }
+ if (attr->elem != NULL) {
cur->elem = xmlStrdup(attr->elem);
- if (attr->name != NULL)
+ if (cur->elem == NULL)
+ goto error;
+ }
+ if (attr->name != NULL) {
cur->name = xmlStrdup(attr->name);
- if (attr->prefix != NULL)
+ if (cur->name == NULL)
+ goto error;
+ }
+ if (attr->prefix != NULL) {
cur->prefix = xmlStrdup(attr->prefix);
- if (attr->defaultValue != NULL)
+ if (cur->prefix == NULL)
+ goto error;
+ }
+ if (attr->defaultValue != NULL) {
cur->defaultValue = xmlStrdup(attr->defaultValue);
+ if (cur->defaultValue == NULL)
+ goto error;
+ }
return(cur);
+
+error:
+ xmlFreeAttribute(cur);
+ return(NULL);
}
/**
@@ -2084,7 +1955,8 @@ xmlCopyAttribute(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
*/
xmlAttributeTablePtr
xmlCopyAttributeTable(xmlAttributeTablePtr table) {
- return((xmlAttributeTablePtr) xmlHashCopy(table, xmlCopyAttribute));
+ return(xmlHashCopySafe(table, xmlCopyAttribute,
+ xmlFreeAttributeTableEntry));
}
#endif /* LIBXML_TREE_ENABLED */
@@ -2094,81 +1966,22 @@ xmlCopyAttributeTable(xmlAttributeTablePtr table) {
* @buf: the XML buffer output
* @attr: An attribute declaration
*
+ * DEPRECATED: Use xmlSaveTree.
+ *
* This will dump the content of the attribute declaration as an XML
* DTD definition
*/
void
xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
+ xmlSaveCtxtPtr save;
+
if ((buf == NULL) || (attr == NULL))
return;
- xmlBufferWriteChar(buf, "elem);
- xmlBufferWriteChar(buf, " ");
- if (attr->prefix != NULL) {
- xmlBufferWriteCHAR(buf, attr->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, attr->name);
- switch (attr->atype) {
- case XML_ATTRIBUTE_CDATA:
- xmlBufferWriteChar(buf, " CDATA");
- break;
- case XML_ATTRIBUTE_ID:
- xmlBufferWriteChar(buf, " ID");
- break;
- case XML_ATTRIBUTE_IDREF:
- xmlBufferWriteChar(buf, " IDREF");
- break;
- case XML_ATTRIBUTE_IDREFS:
- xmlBufferWriteChar(buf, " IDREFS");
- break;
- case XML_ATTRIBUTE_ENTITY:
- xmlBufferWriteChar(buf, " ENTITY");
- break;
- case XML_ATTRIBUTE_ENTITIES:
- xmlBufferWriteChar(buf, " ENTITIES");
- break;
- case XML_ATTRIBUTE_NMTOKEN:
- xmlBufferWriteChar(buf, " NMTOKEN");
- break;
- case XML_ATTRIBUTE_NMTOKENS:
- xmlBufferWriteChar(buf, " NMTOKENS");
- break;
- case XML_ATTRIBUTE_ENUMERATION:
- xmlBufferWriteChar(buf, " (");
- xmlDumpEnumeration(buf, attr->tree);
- break;
- case XML_ATTRIBUTE_NOTATION:
- xmlBufferWriteChar(buf, " NOTATION (");
- xmlDumpEnumeration(buf, attr->tree);
- break;
- default:
- xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
- "Internal: ATTRIBUTE struct corrupted invalid type\n",
- NULL);
- }
- switch (attr->def) {
- case XML_ATTRIBUTE_NONE:
- break;
- case XML_ATTRIBUTE_REQUIRED:
- xmlBufferWriteChar(buf, " #REQUIRED");
- break;
- case XML_ATTRIBUTE_IMPLIED:
- xmlBufferWriteChar(buf, " #IMPLIED");
- break;
- case XML_ATTRIBUTE_FIXED:
- xmlBufferWriteChar(buf, " #FIXED");
- break;
- default:
- xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
- "Internal: ATTRIBUTE struct corrupted invalid def\n",
- NULL);
- }
- if (attr->defaultValue != NULL) {
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteQuotedString(buf, attr->defaultValue);
- }
- xmlBufferWriteChar(buf, ">\n");
+
+ save = xmlSaveToBuffer(buf, NULL, 0);
+ xmlSaveTree(save, (xmlNodePtr) attr);
+ if (xmlSaveFinish(save) != XML_ERR_OK)
+ xmlFree(xmlBufferDetach(buf));
}
/**
@@ -2179,9 +1992,9 @@ xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
* This is used with the hash scan function - just reverses arguments
*/
static void
-xmlDumpAttributeDeclScan(void *attr, void *buf,
+xmlDumpAttributeDeclScan(void *attr, void *save,
const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlDumpAttributeDecl((xmlBufferPtr) buf, (xmlAttributePtr) attr);
+ xmlSaveTree(save, attr);
}
/**
@@ -2189,13 +2002,21 @@ xmlDumpAttributeDeclScan(void *attr, void *buf,
* @buf: the XML buffer output
* @table: An attribute table
*
+ * DEPRECATED: Don't use.
+ *
* This will dump the content of the attribute table as an XML DTD definition
*/
void
xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
+ xmlSaveCtxtPtr save;
+
if ((buf == NULL) || (table == NULL))
return;
- xmlHashScan(table, xmlDumpAttributeDeclScan, buf);
+
+ save = xmlSaveToBuffer(buf, NULL, 0);
+ xmlHashScan(table, xmlDumpAttributeDeclScan, save);
+ if (xmlSaveFinish(save) != XML_ERR_OK)
+ xmlFree(xmlBufferDetach(buf));
}
#endif /* LIBXML_OUTPUT_ENABLED */
@@ -2239,8 +2060,9 @@ xmlNotationPtr
xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd,
const xmlChar *name,
const xmlChar *PublicID, const xmlChar *SystemID) {
- xmlNotationPtr ret;
+ xmlNotationPtr ret = NULL;
xmlNotationTablePtr table;
+ int res;
if (dtd == NULL) {
return(NULL);
@@ -2262,43 +2084,54 @@ xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd,
dict = dtd->doc->dict;
dtd->notations = table = xmlHashCreateDict(0, dict);
- }
- if (table == NULL) {
- xmlVErrMemory(ctxt,
- "xmlAddNotationDecl: Table creation failed!\n");
- return(NULL);
+ if (table == NULL)
+ goto mem_error;
}
ret = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
- if (ret == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
- return(NULL);
- }
+ if (ret == NULL)
+ goto mem_error;
memset(ret, 0, sizeof(xmlNotation));
/*
* fill the structure.
*/
ret->name = xmlStrdup(name);
- if (SystemID != NULL)
+ if (ret->name == NULL)
+ goto mem_error;
+ if (SystemID != NULL) {
ret->SystemID = xmlStrdup(SystemID);
- if (PublicID != NULL)
+ if (ret->SystemID == NULL)
+ goto mem_error;
+ }
+ if (PublicID != NULL) {
ret->PublicID = xmlStrdup(PublicID);
+ if (ret->PublicID == NULL)
+ goto mem_error;
+ }
/*
* Validity Check:
* Check the DTD for previous declarations of the ATTLIST
*/
- if (xmlHashAddEntry(table, name, ret)) {
+ res = xmlHashAdd(table, name, ret);
+ if (res <= 0) {
+ if (res < 0)
+ goto mem_error;
#ifdef LIBXML_VALID_ENABLED
- xmlErrValid(NULL, XML_DTD_NOTATION_REDEFINED,
- "xmlAddNotationDecl: %s already defined\n",
- (const char *) name);
+ xmlErrValid(ctxt, XML_DTD_NOTATION_REDEFINED,
+ "xmlAddNotationDecl: %s already defined\n",
+ (const char *) name);
#endif /* LIBXML_VALID_ENABLED */
xmlFreeNotation(ret);
return(NULL);
}
return(ret);
+
+mem_error:
+ xmlVErrMemory(ctxt);
+ xmlFreeNotation(ret);
+ return(NULL);
}
static void
@@ -2332,23 +2165,29 @@ xmlCopyNotation(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
xmlNotationPtr cur;
cur = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
- if (cur == NULL) {
- xmlVErrMemory(NULL, "malloc failed");
+ if (cur == NULL)
return(NULL);
- }
- if (nota->name != NULL)
+ memset(cur, 0, sizeof(*cur));
+ if (nota->name != NULL) {
cur->name = xmlStrdup(nota->name);
- else
- cur->name = NULL;
- if (nota->PublicID != NULL)
+ if (cur->name == NULL)
+ goto error;
+ }
+ if (nota->PublicID != NULL) {
cur->PublicID = xmlStrdup(nota->PublicID);
- else
- cur->PublicID = NULL;
- if (nota->SystemID != NULL)
+ if (cur->PublicID == NULL)
+ goto error;
+ }
+ if (nota->SystemID != NULL) {
cur->SystemID = xmlStrdup(nota->SystemID);
- else
- cur->SystemID = NULL;
+ if (cur->SystemID == NULL)
+ goto error;
+ }
return(cur);
+
+error:
+ xmlFreeNotation(cur);
+ return(NULL);
}
/**
@@ -2361,7 +2200,7 @@ xmlCopyNotation(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
*/
xmlNotationTablePtr
xmlCopyNotationTable(xmlNotationTablePtr table) {
- return((xmlNotationTablePtr) xmlHashCopy(table, xmlCopyNotation));
+ return(xmlHashCopySafe(table, xmlCopyNotation, xmlFreeNotationTableEntry));
}
#endif /* LIBXML_TREE_ENABLED */
@@ -2371,39 +2210,21 @@ xmlCopyNotationTable(xmlNotationTablePtr table) {
* @buf: the XML buffer output
* @nota: A notation declaration
*
+ * DEPRECATED: Don't use.
+ *
* This will dump the content the notation declaration as an XML DTD definition
*/
void
xmlDumpNotationDecl(xmlBufferPtr buf, xmlNotationPtr nota) {
+ xmlSaveCtxtPtr save;
+
if ((buf == NULL) || (nota == NULL))
return;
- xmlBufferWriteChar(buf, "name);
- if (nota->PublicID != NULL) {
- xmlBufferWriteChar(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf, nota->PublicID);
- if (nota->SystemID != NULL) {
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteQuotedString(buf, nota->SystemID);
- }
- } else {
- xmlBufferWriteChar(buf, " SYSTEM ");
- xmlBufferWriteQuotedString(buf, nota->SystemID);
- }
- xmlBufferWriteChar(buf, " >\n");
-}
-/**
- * xmlDumpNotationDeclScan:
- * @nota: A notation declaration
- * @buf: the XML buffer output
- *
- * This is called with the hash scan function, and just reverses args
- */
-static void
-xmlDumpNotationDeclScan(void *nota, void *buf,
- const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlDumpNotationDecl((xmlBufferPtr) buf, (xmlNotationPtr) nota);
+ save = xmlSaveToBuffer(buf, NULL, 0);
+ xmlSaveNotationDecl(save, nota);
+ if (xmlSaveFinish(save) != XML_ERR_OK)
+ xmlFree(xmlBufferDetach(buf));
}
/**
@@ -2411,13 +2232,21 @@ xmlDumpNotationDeclScan(void *nota, void *buf,
* @buf: the XML buffer output
* @table: A notation table
*
+ * DEPRECATED: Don't use.
+ *
* This will dump the content of the notation table as an XML DTD definition
*/
void
xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
+ xmlSaveCtxtPtr save;
+
if ((buf == NULL) || (table == NULL))
return;
- xmlHashScan(table, xmlDumpNotationDeclScan, buf);
+
+ save = xmlSaveToBuffer(buf, NULL, 0);
+ xmlSaveNotationTable(save, table);
+ if (xmlSaveFinish(save) != XML_ERR_OK)
+ xmlFree(xmlBufferDetach(buf));
}
#endif /* LIBXML_OUTPUT_ENABLED */
@@ -2438,35 +2267,6 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str));
-/**
- * xmlValidNormalizeString:
- * @str: a string
- *
- * Normalize a string in-place.
- */
-static void
-xmlValidNormalizeString(xmlChar *str) {
- xmlChar *dst;
- const xmlChar *src;
-
- if (str == NULL)
- return;
- src = str;
- dst = str;
-
- while (*src == 0x20) src++;
- while (*src != 0) {
- if (*src == 0x20) {
- while (*src == 0x20) src++;
- if (*src != 0)
- *dst++ = 0x20;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
-}
-
static int
xmlIsStreaming(xmlValidCtxtPtr ctxt) {
xmlParserCtxtPtr pctxt;
@@ -2498,36 +2298,46 @@ xmlFreeID(xmlIDPtr id) {
DICT_FREE(id->value)
if (id->name != NULL)
DICT_FREE(id->name)
+ if (id->attr != NULL) {
+ id->attr->id = NULL;
+ id->attr->atype = 0;
+ }
+
xmlFree(id);
}
/**
- * xmlAddID:
- * @ctxt: the validation context
- * @doc: pointer to the document
- * @value: the value name
+ * xmlAddIDInternal:
* @attr: the attribute holding the ID
+ * @value: the attribute (ID) value
+ * @idPtr: pointer to resulting ID
*
* Register a new id declaration
*
- * Returns NULL if not, otherwise the new xmlIDPtr
+ * Returns 1 on success, 0 if the ID already exists, -1 if a memory
+ * allocation fails.
*/
-xmlIDPtr
-xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
- xmlAttrPtr attr) {
- xmlIDPtr ret;
+static int
+xmlAddIDInternal(xmlAttrPtr attr, const xmlChar *value, xmlIDPtr *idPtr) {
+ xmlDocPtr doc;
+ xmlIDPtr id;
xmlIDTablePtr table;
+ int ret;
- if (doc == NULL) {
- return(NULL);
- }
- if ((value == NULL) || (value[0] == 0)) {
- return(NULL);
- }
- if (attr == NULL) {
- return(NULL);
- }
+ if (idPtr != NULL)
+ *idPtr = NULL;
+ if ((value == NULL) || (value[0] == 0))
+ return(0);
+ if (attr == NULL)
+ return(0);
+
+ doc = attr->doc;
+ if (doc == NULL)
+ return(0);
+
+ if (attr->id != NULL)
+ xmlRemoveID(doc, attr);
/*
* Create the ID table if needed.
@@ -2535,57 +2345,109 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
table = (xmlIDTablePtr) doc->ids;
if (table == NULL) {
doc->ids = table = xmlHashCreateDict(0, doc->dict);
- }
- if (table == NULL) {
- xmlVErrMemory(ctxt,
- "xmlAddID: Table creation failed!\n");
- return(NULL);
+ if (table == NULL)
+ return(-1);
+ } else {
+ id = xmlHashLookup(table, value);
+ if (id != NULL) {
+ if (id->attr != NULL) {
+ id->attr->id = NULL;
+ id->attr->atype = 0;
+ }
+ ret = 0;
+ goto done;
+ }
}
- ret = (xmlIDPtr) xmlMalloc(sizeof(xmlID));
- if (ret == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
- return(NULL);
- }
+ id = (xmlIDPtr) xmlMalloc(sizeof(xmlID));
+ if (id == NULL)
+ return(-1);
+ memset(id, 0, sizeof(*id));
/*
* fill the structure.
*/
- ret->value = xmlStrdup(value);
- ret->doc = doc;
- if (xmlIsStreaming(ctxt)) {
- /*
- * Operating in streaming mode, attr is gonna disappear
- */
- if (doc->dict != NULL)
- ret->name = xmlDictLookup(doc->dict, attr->name, -1);
- else
- ret->name = xmlStrdup(attr->name);
- ret->attr = NULL;
- } else {
- ret->attr = attr;
- ret->name = NULL;
+ id->doc = doc;
+ id->value = xmlStrdup(value);
+ if (id->value == NULL) {
+ xmlFreeID(id);
+ return(-1);
}
- ret->lineno = xmlGetLineNo(attr->parent);
- if (xmlHashAddEntry(table, value, ret) < 0) {
-#ifdef LIBXML_VALID_ENABLED
- /*
- * The id is already defined in this DTD.
- */
- if (ctxt != NULL) {
- xmlErrValidNode(ctxt, attr->parent, XML_DTD_ID_REDEFINED,
- "ID %s already defined\n", value, NULL, NULL);
- }
-#endif /* LIBXML_VALID_ENABLED */
- xmlFreeID(ret);
- return(NULL);
+ if (xmlHashAddEntry(table, value, id) < 0) {
+ xmlFreeID(id);
+ return(-1);
}
- if (attr != NULL)
- attr->atype = XML_ATTRIBUTE_ID;
+
+ ret = 1;
+ if (idPtr != NULL)
+ *idPtr = id;
+
+done:
+ id->attr = attr;
+ id->lineno = xmlGetLineNo(attr->parent);
+ attr->atype = XML_ATTRIBUTE_ID;
+ attr->id = id;
+
return(ret);
}
+/**
+ * xmlAddIDSafe:
+ * @attr: the attribute holding the ID
+ * @value: the attribute (ID) value
+ *
+ * Register a new id declaration
+ *
+ * Available since 2.13.0.
+ *
+ * Returns 1 on success, 0 if the ID already exists, -1 if a memory
+ * allocation fails.
+ */
+int
+xmlAddIDSafe(xmlAttrPtr attr, const xmlChar *value) {
+ return(xmlAddIDInternal(attr, value, NULL));
+}
+
+/**
+ * xmlAddID:
+ * @ctxt: the validation context
+ * @doc: pointer to the document
+ * @value: the value name
+ * @attr: the attribute holding the ID
+ *
+ * Register a new id declaration
+ *
+ * Returns NULL if not, otherwise the new xmlIDPtr
+ */
+xmlIDPtr
+xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
+ xmlAttrPtr attr) {
+ xmlIDPtr id;
+ int res;
+
+ if ((attr == NULL) || (doc != attr->doc))
+ return(NULL);
+
+ res = xmlAddIDInternal(attr, value, &id);
+ if (res < 0) {
+ xmlVErrMemory(ctxt);
+ }
+#ifdef LIBXML_VALID_ENABLED
+ else if (res == 0) {
+ if (ctxt != NULL) {
+ /*
+ * The id is already defined in this DTD.
+ */
+ xmlErrValidNode(ctxt, attr->parent, XML_DTD_ID_REDEFINED,
+ "ID %s already defined\n", value, NULL, NULL);
+ }
+ }
+#endif /* LIBXML_VALID_ENABLED */
+
+ return(id);
+}
+
static void
xmlFreeIDTableEntry(void *id, const xmlChar *name ATTRIBUTE_UNUSED) {
xmlFreeID((xmlIDPtr) id);
@@ -2613,57 +2475,67 @@ xmlFreeIDTable(xmlIDTablePtr table) {
* of HTML documents parsed with the HTML parser, then ID detection is
* done systematically.
*
- * Returns 0 or 1 depending on the lookup result
+ * Returns 0 or 1 depending on the lookup result or -1 if a memory allocation
+ * failed.
*/
int
xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
- if ((attr == NULL) || (attr->name == NULL)) return(0);
- if ((attr->ns != NULL) && (attr->ns->prefix != NULL) &&
- (!strcmp((char *) attr->name, "id")) &&
- (!strcmp((char *) attr->ns->prefix, "xml")))
- return(1);
- if (doc == NULL) return(0);
- if ((doc->intSubset == NULL) && (doc->extSubset == NULL) &&
- (doc->type != XML_HTML_DOCUMENT_NODE)) {
- return(0);
- } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
- if ((xmlStrEqual(BAD_CAST "id", attr->name)) ||
- ((xmlStrEqual(BAD_CAST "name", attr->name)) &&
- ((elem == NULL) || (xmlStrEqual(elem->name, BAD_CAST "a")))))
+ if ((attr == NULL) || (attr->name == NULL))
+ return(0);
+
+ if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
+ if (xmlStrEqual(BAD_CAST "id", attr->name))
+ return(1);
+
+ if ((elem == NULL) || (elem->type != XML_ELEMENT_NODE))
+ return(0);
+
+ if ((xmlStrEqual(BAD_CAST "name", attr->name)) &&
+ (xmlStrEqual(elem->name, BAD_CAST "a")))
return(1);
- return(0);
- } else if (elem == NULL) {
- return(0);
} else {
xmlAttributePtr attrDecl = NULL;
+ xmlChar felem[50];
+ xmlChar *fullelemname;
+ const xmlChar *aprefix;
- xmlChar felem[50], fattr[50];
- xmlChar *fullelemname, *fullattrname;
+ if ((attr->ns != NULL) && (attr->ns->prefix != NULL) &&
+ (!strcmp((char *) attr->name, "id")) &&
+ (!strcmp((char *) attr->ns->prefix, "xml")))
+ return(1);
+
+ if ((doc == NULL) ||
+ ((doc->intSubset == NULL) && (doc->extSubset == NULL)))
+ return(0);
+
+ if ((elem == NULL) ||
+ (elem->type != XML_ELEMENT_NODE) ||
+ (elem->name == NULL))
+ return(0);
fullelemname = (elem->ns != NULL && elem->ns->prefix != NULL) ?
xmlBuildQName(elem->name, elem->ns->prefix, felem, 50) :
(xmlChar *)elem->name;
+ if (fullelemname == NULL)
+ return(-1);
- fullattrname = (attr->ns != NULL && attr->ns->prefix != NULL) ?
- xmlBuildQName(attr->name, attr->ns->prefix, fattr, 50) :
- (xmlChar *)attr->name;
+ aprefix = (attr->ns != NULL) ? attr->ns->prefix : NULL;
- if (fullelemname != NULL && fullattrname != NULL) {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullelemname,
- fullattrname);
+ if (fullelemname != NULL) {
+ attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, fullelemname,
+ attr->name, aprefix);
if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullelemname,
- fullattrname);
+ attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, fullelemname,
+ attr->name, aprefix);
}
- if ((fullattrname != fattr) && (fullattrname != attr->name))
- xmlFree(fullattrname);
if ((fullelemname != felem) && (fullelemname != elem->name))
xmlFree(fullelemname);
if ((attrDecl != NULL) && (attrDecl->atype == XML_ATTRIBUTE_ID))
return(1);
}
+
return(0);
}
@@ -2678,31 +2550,18 @@ xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
*/
int
xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
- xmlIDTablePtr table;
- xmlIDPtr id;
- xmlChar *ID;
+ xmlIDTablePtr table;
if (doc == NULL) return(-1);
- if (attr == NULL) return(-1);
+ if ((attr == NULL) || (attr->id == NULL)) return(-1);
table = (xmlIDTablePtr) doc->ids;
if (table == NULL)
return(-1);
- ID = xmlNodeListGetString(doc, attr->children, 1);
- if (ID == NULL)
- return(-1);
- xmlValidNormalizeString(ID);
-
- id = xmlHashLookup(table, ID);
- if (id == NULL || id->attr != attr) {
- xmlFree(ID);
+ if (xmlHashRemoveEntry(table, attr->id->value, xmlFreeIDTableEntry) < 0)
return(-1);
- }
- xmlHashRemoveEntry(table, ID, xmlFreeIDTableEntry);
- xmlFree(ID);
- attr->atype = 0;
return(0);
}
@@ -2847,7 +2706,7 @@ xmlDummyCompare(const void *data0 ATTRIBUTE_UNUSED,
xmlRefPtr
xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
xmlAttrPtr attr) {
- xmlRefPtr ret;
+ xmlRefPtr ret = NULL;
xmlRefTablePtr table;
xmlListPtr ref_list;
@@ -2867,28 +2726,28 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
table = (xmlRefTablePtr) doc->refs;
if (table == NULL) {
doc->refs = table = xmlHashCreateDict(0, doc->dict);
- }
- if (table == NULL) {
- xmlVErrMemory(ctxt,
- "xmlAddRef: Table creation failed!\n");
- return(NULL);
+ if (table == NULL)
+ goto failed;
}
ret = (xmlRefPtr) xmlMalloc(sizeof(xmlRef));
- if (ret == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
- return(NULL);
- }
+ if (ret == NULL)
+ goto failed;
+ memset(ret, 0, sizeof(*ret));
/*
* fill the structure.
*/
ret->value = xmlStrdup(value);
+ if (ret->value == NULL)
+ goto failed;
if (xmlIsStreaming(ctxt)) {
/*
* Operating in streaming mode, attr is gonna disappear
*/
ret->name = xmlStrdup(attr->name);
+ if (ret->name == NULL)
+ goto failed;
ret->attr = NULL;
} else {
ret->name = NULL;
@@ -2904,28 +2763,22 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
*/
if (NULL == (ref_list = xmlHashLookup(table, value))) {
- if (NULL == (ref_list = xmlListCreate(xmlFreeRef, xmlDummyCompare))) {
- xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
- "xmlAddRef: Reference list creation failed!\n",
- NULL);
+ int res;
+
+ if (NULL == (ref_list = xmlListCreate(xmlFreeRef, xmlDummyCompare)))
goto failed;
- }
- if (xmlHashAddEntry(table, value, ref_list) < 0) {
+ res = xmlHashAdd(table, value, ref_list);
+ if (res <= 0) {
xmlListDelete(ref_list);
- xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
- "xmlAddRef: Reference list insertion failed!\n",
- NULL);
goto failed;
}
}
- if (xmlListAppend(ref_list, ret) != 0) {
- xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
- "xmlAddRef: Reference list insertion failed!\n",
- NULL);
+ if (xmlListAppend(ref_list, ret) != 0)
goto failed;
- }
return(ret);
+
failed:
+ xmlVErrMemory(ctxt);
if (ret != NULL) {
if (ret->value != NULL)
xmlFree((char *)ret->value);
@@ -2979,12 +2832,15 @@ xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
return(0);
} else {
xmlAttributePtr attrDecl;
+ const xmlChar *aprefix;
if (elem == NULL) return(0);
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
+ aprefix = (attr->ns != NULL) ? attr->ns->prefix : NULL;
+ attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name, attr->name,
+ aprefix);
if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
- elem->name, attr->name);
+ attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name, attr->name,
+ aprefix);
if ((attrDecl != NULL) &&
(attrDecl->atype == XML_ATTRIBUTE_IDREF ||
@@ -3047,7 +2903,7 @@ xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
/*If the list is empty then remove the list entry in the hash */
if (xmlListEmpty(ref_list))
- xmlHashUpdateEntry(table, ID, NULL, xmlFreeRefTableEntry);
+ xmlHashRemoveEntry(table, ID, xmlFreeRefTableEntry);
xmlFree(ID);
return(0);
}
@@ -3095,6 +2951,8 @@ xmlGetRefs(xmlDocPtr doc, const xmlChar *ID) {
*
* Search the DTD for the description of this element
*
+ * NOTE: A NULL return value can also mean that a memory allocation failed.
+ *
* returns the xmlElementPtr if found or NULL
*/
@@ -3102,21 +2960,26 @@ xmlElementPtr
xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) {
xmlElementTablePtr table;
xmlElementPtr cur;
- xmlChar *uqname = NULL, *prefix = NULL;
+ const xmlChar *localname;
+ xmlChar *prefix;
+
+ if ((dtd == NULL) || (dtd->elements == NULL) ||
+ (name == NULL))
+ return(NULL);
- if ((dtd == NULL) || (name == NULL)) return(NULL);
- if (dtd->elements == NULL)
- return(NULL);
table = (xmlElementTablePtr) dtd->elements;
+ if (table == NULL)
+ return(NULL);
- uqname = xmlSplitQName2(name, &prefix);
- if (uqname != NULL)
- name = uqname;
- cur = xmlHashLookup2(table, name, prefix);
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
+ localname = xmlSplitQName4(name, &prefix);
+ if (localname == NULL)
+ return(NULL);
+ cur = xmlHashLookup2(table, localname, prefix);
+ if (prefix != NULL)
+ xmlFree(prefix);
return(cur);
}
+
/**
* xmlGetDtdElementDesc2:
* @dtd: a pointer to the DtD to search
@@ -3129,66 +2992,64 @@ xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) {
*/
static xmlElementPtr
-xmlGetDtdElementDesc2(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
- int create) {
+xmlGetDtdElementDesc2(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name) {
xmlElementTablePtr table;
- xmlElementPtr cur;
- xmlChar *uqname = NULL, *prefix = NULL;
+ xmlElementPtr cur = NULL;
+ const xmlChar *localName;
+ xmlChar *prefix = NULL;
if (dtd == NULL) return(NULL);
+
+ /*
+ * Create the Element table if needed.
+ */
if (dtd->elements == NULL) {
xmlDictPtr dict = NULL;
if (dtd->doc != NULL)
dict = dtd->doc->dict;
- if (!create)
- return(NULL);
- /*
- * Create the Element table if needed.
- */
- table = (xmlElementTablePtr) dtd->elements;
- if (table == NULL) {
- table = xmlHashCreateDict(0, dict);
- dtd->elements = (void *) table;
- }
- if (table == NULL) {
- xmlVErrMemory(ctxt, "element table allocation failed");
- return(NULL);
- }
+ dtd->elements = xmlHashCreateDict(0, dict);
+ if (dtd->elements == NULL)
+ goto mem_error;
}
table = (xmlElementTablePtr) dtd->elements;
- uqname = xmlSplitQName2(name, &prefix);
- if (uqname != NULL)
- name = uqname;
- cur = xmlHashLookup2(table, name, prefix);
- if ((cur == NULL) && (create)) {
+ localName = xmlSplitQName4(name, &prefix);
+ if (localName == NULL)
+ goto mem_error;
+ cur = xmlHashLookup2(table, localName, prefix);
+ if (cur == NULL) {
cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
- if (cur == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
- goto error;
- }
+ if (cur == NULL)
+ goto mem_error;
memset(cur, 0, sizeof(xmlElement));
cur->type = XML_ELEMENT_DECL;
+ cur->doc = dtd->doc;
/*
* fill the structure.
*/
- cur->name = xmlStrdup(name);
- cur->prefix = xmlStrdup(prefix);
+ cur->name = xmlStrdup(localName);
+ if (cur->name == NULL)
+ goto mem_error;
+ cur->prefix = prefix;
+ prefix = NULL;
cur->etype = XML_ELEMENT_TYPE_UNDEFINED;
- if (xmlHashAddEntry2(table, name, prefix, cur) < 0) {
- xmlVErrMemory(ctxt, "adding entry failed");
- xmlFreeElement(cur);
- cur = NULL;
- }
+ if (xmlHashAdd2(table, localName, cur->prefix, cur) <= 0)
+ goto mem_error;
}
-error:
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
+
+ if (prefix != NULL)
+ xmlFree(prefix);
return(cur);
+
+mem_error:
+ xmlVErrMemory(ctxt);
+ xmlFree(prefix);
+ xmlFreeElement(cur);
+ return(NULL);
}
/**
@@ -3230,23 +3091,23 @@ xmlAttributePtr
xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) {
xmlAttributeTablePtr table;
xmlAttributePtr cur;
- xmlChar *uqname = NULL, *prefix = NULL;
+ const xmlChar *localname;
+ xmlChar *prefix = NULL;
- if (dtd == NULL) return(NULL);
- if (dtd->attributes == NULL) return(NULL);
+ if ((dtd == NULL) || (dtd->attributes == NULL) ||
+ (elem == NULL) || (name == NULL))
+ return(NULL);
table = (xmlAttributeTablePtr) dtd->attributes;
if (table == NULL)
return(NULL);
- uqname = xmlSplitQName2(name, &prefix);
-
- if (uqname != NULL) {
- cur = xmlHashLookup3(table, uqname, prefix, elem);
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
- } else
- cur = xmlHashLookup3(table, name, NULL, elem);
+ localname = xmlSplitQName4(name, &prefix);
+ if (localname == NULL)
+ return(NULL);
+ cur = xmlHashLookup3(table, localname, prefix, elem);
+ if (prefix != NULL)
+ xmlFree(prefix);
return(cur);
}
@@ -3303,6 +3164,8 @@ xmlGetDtdNotationDesc(xmlDtdPtr dtd, const xmlChar *name) {
* @doc: the document
* @notationName: the notation name to check
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Validate that the given name match a notation declaration.
* - [ VC: Notation Declared ]
*
@@ -3370,6 +3233,35 @@ xmlIsMixedElement(xmlDocPtr doc, const xmlChar *name) {
#ifdef LIBXML_VALID_ENABLED
+/**
+ * xmlValidNormalizeString:
+ * @str: a string
+ *
+ * Normalize a string in-place.
+ */
+static void
+xmlValidNormalizeString(xmlChar *str) {
+ xmlChar *dst;
+ const xmlChar *src;
+
+ if (str == NULL)
+ return;
+ src = str;
+ dst = str;
+
+ while (*src == 0x20) src++;
+ while (*src != 0) {
+ if (*src == 0x20) {
+ while (*src == 0x20) src++;
+ if (*src != 0)
+ *dst++ = 0x20;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
static int
xmlIsDocNameStartChar(xmlDocPtr doc, int c) {
if ((doc == NULL) || (doc->properties & XML_DOC_OLD10) == 0) {
@@ -3689,6 +3581,8 @@ xmlValidateNmtokensValue(const xmlChar *value) {
* @doc: a document instance
* @nota: a notation definition
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Try to validate a single notation definition
* basically it does the following checks as described by the
* XML-1.0 recommendation:
@@ -3745,6 +3639,8 @@ xmlValidateAttributeValueInternal(xmlDocPtr doc, xmlAttributeType type,
* @type: an attribute type
* @value: an attribute value
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Validate that the given attribute value match the proper production
*
* [ VC: ID ]
@@ -3840,8 +3736,10 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlEntityPtr ent;
dup = xmlStrdup(value);
- if (dup == NULL)
+ if (dup == NULL) {
+ xmlVErrMemory(ctxt);
return(0);
+ }
cur = dup;
while (*cur != 0) {
nam = cur;
@@ -3899,6 +3797,8 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
* @value: the attribute value
* @ctxt: the validation context or NULL
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Does the validation related extra step of the normalization of attribute
* values:
*
@@ -3919,6 +3819,8 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
xmlChar *ret;
xmlAttributePtr attrDecl = NULL;
+ const xmlChar *localName;
+ xmlChar *prefix = NULL;
int extsubset = 0;
if (doc == NULL) return(NULL);
@@ -3926,38 +3828,47 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
if (name == NULL) return(NULL);
if (value == NULL) return(NULL);
- if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
- xmlChar fn[50];
- xmlChar *fullname;
+ localName = xmlSplitQName4(name, &prefix);
+ if (localName == NULL)
+ goto mem_error;
- fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
- if (fullname == NULL)
- return(NULL);
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, name);
+ if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
+ xmlChar buf[50];
+ xmlChar *elemname;
+
+ elemname = xmlBuildQName(elem->name, elem->ns->prefix, buf, 50);
+ if (elemname == NULL)
+ goto mem_error;
+ if (doc->intSubset != NULL)
+ attrDecl = xmlHashLookup3(doc->intSubset->attributes, localName,
+ prefix, elemname);
if ((attrDecl == NULL) && (doc->extSubset != NULL)) {
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname, name);
+ attrDecl = xmlHashLookup3(doc->extSubset->attributes, localName,
+ prefix, elemname);
if (attrDecl != NULL)
extsubset = 1;
}
- if ((fullname != fn) && (fullname != elem->name))
- xmlFree(fullname);
+ if ((elemname != buf) && (elemname != elem->name))
+ xmlFree(elemname);
}
if ((attrDecl == NULL) && (doc->intSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
+ attrDecl = xmlHashLookup3(doc->intSubset->attributes, localName,
+ prefix, elem->name);
if ((attrDecl == NULL) && (doc->extSubset != NULL)) {
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name);
+ attrDecl = xmlHashLookup3(doc->extSubset->attributes, localName,
+ prefix, elem->name);
if (attrDecl != NULL)
extsubset = 1;
}
if (attrDecl == NULL)
- return(NULL);
+ goto done;
if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
- return(NULL);
+ goto done;
ret = xmlStrdup(value);
if (ret == NULL)
- return(NULL);
+ goto mem_error;
xmlValidNormalizeString(ret);
if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
@@ -3965,7 +3876,16 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
name, elem->name, NULL);
ctxt->valid = 0;
}
+
+ xmlFree(prefix);
return(ret);
+
+mem_error:
+ xmlVErrMemory(ctxt);
+
+done:
+ xmlFree(prefix);
+ return(NULL);
}
/**
@@ -3975,6 +3895,8 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
* @name: the attribute name
* @value: the attribute value
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Does the validation related extra step of the normalization of attribute
* values:
*
@@ -4038,6 +3960,8 @@ xmlValidateAttributeIdCallback(void *payload, void *data,
* @doc: a document instance
* @attr: an attribute definition
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Try to validate a single attribute definition
* basically it does the following checks as described by the
* XML-1.0 recommendation:
@@ -4083,13 +4007,23 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
/* One ID per Element Type */
if (attr->atype == XML_ATTRIBUTE_ID) {
+ xmlElementPtr elem = NULL;
+ const xmlChar *elemLocalName;
+ xmlChar *elemPrefix;
int nbId;
+ elemLocalName = xmlSplitQName4(attr->elem, &elemPrefix);
+ if (elemLocalName == NULL) {
+ xmlVErrMemory(ctxt);
+ return(0);
+ }
+
/* the trick is that we parse DtD as their own internal subset */
- xmlElementPtr elem = xmlGetDtdElementDesc(doc->intSubset,
- attr->elem);
+ if (doc->intSubset != NULL)
+ elem = xmlHashLookup2(doc->intSubset->elements,
+ elemLocalName, elemPrefix);
if (elem != NULL) {
- nbId = xmlScanIDAttributeDecl(NULL, elem, 0);
+ nbId = xmlScanIDAttributeDecl(ctxt, elem, 0);
} else {
xmlAttributeTablePtr table;
@@ -4109,22 +4043,28 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlErrValidNodeNr(ctxt, (xmlNodePtr) attr, XML_DTD_ID_SUBSET,
"Element %s has %d ID attribute defined in the internal subset : %s\n",
attr->elem, nbId, attr->name);
+ ret = 0;
} else if (doc->extSubset != NULL) {
int extId = 0;
- elem = xmlGetDtdElementDesc(doc->extSubset, attr->elem);
+ elem = xmlHashLookup2(doc->extSubset->elements,
+ elemLocalName, elemPrefix);
if (elem != NULL) {
- extId = xmlScanIDAttributeDecl(NULL, elem, 0);
+ extId = xmlScanIDAttributeDecl(ctxt, elem, 0);
}
if (extId > 1) {
xmlErrValidNodeNr(ctxt, (xmlNodePtr) attr, XML_DTD_ID_SUBSET,
"Element %s has %d ID attribute defined in the external subset : %s\n",
attr->elem, extId, attr->name);
+ ret = 0;
} else if (extId + nbId > 1) {
xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ID_SUBSET,
"Element %s has ID attributes defined in the internal and external subset : %s\n",
attr->elem, attr->name, NULL);
+ ret = 0;
}
}
+
+ xmlFree(elemPrefix);
}
/* Validity Constraint: Enumeration */
@@ -4151,6 +4091,8 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
* @doc: a document instance
* @elem: an element definition
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Try to validate a single element definition
* basically it does the following checks as described by the
* XML-1.0 recommendation:
@@ -4166,6 +4108,8 @@ xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlElementPtr elem) {
int ret = 1;
xmlElementPtr tst;
+ const xmlChar *localName;
+ xmlChar *prefix;
CHECK_DTD;
@@ -4229,32 +4173,47 @@ xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
}
}
+ localName = xmlSplitQName4(elem->name, &prefix);
+ if (localName == NULL) {
+ xmlVErrMemory(ctxt);
+ return(0);
+ }
+
/* VC: Unique Element Type Declaration */
- tst = xmlGetDtdElementDesc(doc->intSubset, elem->name);
- if ((tst != NULL ) && (tst != elem) &&
- ((tst->prefix == elem->prefix) ||
- (xmlStrEqual(tst->prefix, elem->prefix))) &&
- (tst->etype != XML_ELEMENT_TYPE_UNDEFINED)) {
- xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_ELEM_REDEFINED,
- "Redefinition of element %s\n",
- elem->name, NULL, NULL);
- ret = 0;
+ if (doc->intSubset != NULL) {
+ tst = xmlHashLookup2(doc->intSubset->elements, localName, prefix);
+
+ if ((tst != NULL ) && (tst != elem) &&
+ ((tst->prefix == elem->prefix) ||
+ (xmlStrEqual(tst->prefix, elem->prefix))) &&
+ (tst->etype != XML_ELEMENT_TYPE_UNDEFINED)) {
+ xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_ELEM_REDEFINED,
+ "Redefinition of element %s\n",
+ elem->name, NULL, NULL);
+ ret = 0;
+ }
}
- tst = xmlGetDtdElementDesc(doc->extSubset, elem->name);
- if ((tst != NULL ) && (tst != elem) &&
- ((tst->prefix == elem->prefix) ||
- (xmlStrEqual(tst->prefix, elem->prefix))) &&
- (tst->etype != XML_ELEMENT_TYPE_UNDEFINED)) {
- xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_ELEM_REDEFINED,
- "Redefinition of element %s\n",
- elem->name, NULL, NULL);
- ret = 0;
+ if (doc->extSubset != NULL) {
+ tst = xmlHashLookup2(doc->extSubset->elements, localName, prefix);
+
+ if ((tst != NULL ) && (tst != elem) &&
+ ((tst->prefix == elem->prefix) ||
+ (xmlStrEqual(tst->prefix, elem->prefix))) &&
+ (tst->etype != XML_ELEMENT_TYPE_UNDEFINED)) {
+ xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_ELEM_REDEFINED,
+ "Redefinition of element %s\n",
+ elem->name, NULL, NULL);
+ ret = 0;
+ }
}
+
/* One ID per Element Type
* already done when registering the attribute
if (xmlScanIDAttributeDecl(ctxt, elem) > 1) {
ret = 0;
} */
+
+ xmlFree(prefix);
return(ret);
}
@@ -4266,6 +4225,8 @@ xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
* @attr: an attribute instance
* @value: the attribute value (without entities processing)
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Try to validate a single attribute for an element
* basically it does the following checks as described by the
* XML-1.0 recommendation:
@@ -4288,6 +4249,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value)
{
xmlAttributePtr attrDecl = NULL;
+ const xmlChar *aprefix;
int val;
int ret = 1;
@@ -4295,42 +4257,31 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
if ((elem == NULL) || (elem->name == NULL)) return(0);
if ((attr == NULL) || (attr->name == NULL)) return(0);
+ aprefix = (attr->ns != NULL) ? attr->ns->prefix : NULL;
+
if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
xmlChar fn[50];
xmlChar *fullname;
fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
- if (fullname == NULL)
+ if (fullname == NULL) {
+ xmlVErrMemory(ctxt);
return(0);
- if (attr->ns != NULL) {
- attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, fullname,
- attr->name, attr->ns->prefix);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, fullname,
- attr->name, attr->ns->prefix);
- } else {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, attr->name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
- fullname, attr->name);
- }
+ }
+ attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, fullname,
+ attr->name, aprefix);
+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
+ attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, fullname,
+ attr->name, aprefix);
if ((fullname != fn) && (fullname != elem->name))
xmlFree(fullname);
}
if (attrDecl == NULL) {
- if (attr->ns != NULL) {
- attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
- attr->name, attr->ns->prefix);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
- attr->name, attr->ns->prefix);
- } else {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset,
- elem->name, attr->name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
- elem->name, attr->name);
- }
+ attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
+ attr->name, aprefix);
+ if ((attrDecl == NULL) && (doc->extSubset != NULL))
+ attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
+ attr->name, aprefix);
}
@@ -4341,6 +4292,8 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
attr->name, elem->name, NULL);
return(0);
}
+ if (attr->atype == XML_ATTRIBUTE_ID)
+ xmlRemoveID(doc, attr);
attr->atype = attrDecl->atype;
val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
@@ -4443,6 +4396,8 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
* @ns: an namespace declaration instance
* @value: the attribute value (without entities processing)
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Try to validate a single namespace declaration for an element
* basically it does the following checks as described by the
* XML-1.0 recommendation:
@@ -4478,7 +4433,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
fullname = xmlBuildQName(elem->name, prefix, fn, 50);
if (fullname == NULL) {
- xmlVErrMemory(ctxt, "Validating namespace");
+ xmlVErrMemory(ctxt);
return(0);
}
if (ns->prefix != NULL) {
@@ -4488,11 +4443,11 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, fullname,
ns->prefix, BAD_CAST "xmlns");
} else {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname,
- BAD_CAST "xmlns");
+ attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, fullname,
+ BAD_CAST "xmlns", NULL);
if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname,
- BAD_CAST "xmlns");
+ attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, fullname,
+ BAD_CAST "xmlns", NULL);
}
if ((fullname != fn) && (fullname != elem->name))
xmlFree(fullname);
@@ -4505,11 +4460,11 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
ns->prefix, BAD_CAST "xmlns");
} else {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset,
- elem->name, BAD_CAST "xmlns");
+ attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
+ BAD_CAST "xmlns", NULL);
if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
- elem->name, BAD_CAST "xmlns");
+ attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
+ BAD_CAST "xmlns", NULL);
}
}
@@ -5072,7 +5027,8 @@ xmlSnprintfElements(char *buf, int size, xmlNodePtr node, int glob) {
strcat(buf, " ...");
return;
}
- strcat(buf, (char *) cur->name);
+ if (cur->name != NULL)
+ strcat(buf, (char *) cur->name);
if (cur->next != NULL)
strcat(buf, " ");
break;
@@ -5158,67 +5114,74 @@ xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
ctxt->nodeNr = 0;
ctxt->nodeTab = NULL;
exec = xmlRegNewExecCtxt(elemDecl->contModel, NULL, NULL);
- if (exec != NULL) {
- cur = child;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_ENTITY_REF_NODE:
- /*
- * Push the current node to be able to roll back
- * and process within the entity
- */
- if ((cur->children != NULL) &&
- (cur->children->children != NULL)) {
- nodeVPush(ctxt, cur);
- cur = cur->children->children;
- continue;
- }
- break;
- case XML_TEXT_NODE:
- if (xmlIsBlankNode(cur))
- break;
- ret = 0;
- goto fail;
- case XML_CDATA_SECTION_NODE:
- /* TODO */
- ret = 0;
- goto fail;
- case XML_ELEMENT_NODE:
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlChar fn[50];
- xmlChar *fullname;
-
- fullname = xmlBuildQName(cur->name,
- cur->ns->prefix, fn, 50);
- if (fullname == NULL) {
- ret = -1;
- goto fail;
- }
- ret = xmlRegExecPushString(exec, fullname, NULL);
- if ((fullname != fn) && (fullname != cur->name))
- xmlFree(fullname);
- } else {
- ret = xmlRegExecPushString(exec, cur->name, NULL);
- }
- break;
- default:
- break;
- }
- /*
- * Switch to next element
- */
- cur = cur->next;
- while (cur == NULL) {
- cur = nodeVPop(ctxt);
- if (cur == NULL)
- break;
- cur = cur->next;
- }
- }
- ret = xmlRegExecPushString(exec, NULL, NULL);
+ if (exec == NULL) {
+ xmlVErrMemory(ctxt);
+ return(-1);
+ }
+ cur = child;
+ while (cur != NULL) {
+ switch (cur->type) {
+ case XML_ENTITY_REF_NODE:
+ /*
+ * Push the current node to be able to roll back
+ * and process within the entity
+ */
+ if ((cur->children != NULL) &&
+ (cur->children->children != NULL)) {
+ nodeVPush(ctxt, cur);
+ cur = cur->children->children;
+ continue;
+ }
+ break;
+ case XML_TEXT_NODE:
+ if (xmlIsBlankNode(cur))
+ break;
+ ret = 0;
+ goto fail;
+ case XML_CDATA_SECTION_NODE:
+ /* TODO */
+ ret = 0;
+ goto fail;
+ case XML_ELEMENT_NODE:
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ xmlChar fn[50];
+ xmlChar *fullname;
+
+ fullname = xmlBuildQName(cur->name,
+ cur->ns->prefix, fn, 50);
+ if (fullname == NULL) {
+ xmlVErrMemory(ctxt);
+ ret = -1;
+ goto fail;
+ }
+ ret = xmlRegExecPushString(exec, fullname, NULL);
+ if ((fullname != fn) && (fullname != cur->name))
+ xmlFree(fullname);
+ } else {
+ ret = xmlRegExecPushString(exec, cur->name, NULL);
+ }
+ break;
+ default:
+ break;
+ }
+ if (ret == XML_REGEXP_OUT_OF_MEMORY)
+ xmlVErrMemory(ctxt);
+ /*
+ * Switch to next element
+ */
+ cur = cur->next;
+ while (cur == NULL) {
+ cur = nodeVPop(ctxt);
+ if (cur == NULL)
+ break;
+ cur = cur->next;
+ }
+ }
+ ret = xmlRegExecPushString(exec, NULL, NULL);
+ if (ret == XML_REGEXP_OUT_OF_MEMORY)
+ xmlVErrMemory(ctxt);
fail:
- xmlRegFreeExecCtxt(exec);
- }
+ xmlRegFreeExecCtxt(exec);
}
#else /* LIBXML_REGEXP_ENABLED */
/*
@@ -5228,7 +5191,7 @@ xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
ctxt->vstateTab = (xmlValidState *) xmlMalloc(
ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
if (ctxt->vstateTab == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
+ xmlVErrMemory(ctxt);
return(-1);
}
/*
@@ -5287,7 +5250,7 @@ xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
*/
tmp = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
if (tmp == NULL) {
- xmlVErrMemory(ctxt, "malloc failed");
+ xmlVErrMemory(ctxt);
xmlFreeNodeList(repl);
ret = -1;
goto done;
@@ -5587,9 +5550,9 @@ xmlValidGetElemDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
* full QName but in that case being flexible makes sense.
*/
if (elemDecl == NULL) {
- elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
+ elemDecl = xmlGetDtdQElementDesc(doc->intSubset, elem->name, NULL);
if ((elemDecl == NULL) && (doc->extSubset != NULL)) {
- elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name);
+ elemDecl = xmlGetDtdQElementDesc(doc->extSubset, elem->name, NULL);
if ((elemDecl != NULL) && (extsubset != NULL))
*extsubset = 1;
}
@@ -5611,6 +5574,8 @@ xmlValidGetElemDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
* @elem: an element instance
* @qname: the qualified name as appearing in the serialization
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Push a new element start on the validation stack.
*
* returns 1 if no validation problem was found or 0 otherwise
@@ -5679,6 +5644,10 @@ xmlValidatePushElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
*/
if (state->exec != NULL) {
ret = xmlRegExecPushString(state->exec, qname, NULL);
+ if (ret == XML_REGEXP_OUT_OF_MEMORY) {
+ xmlVErrMemory(ctxt);
+ return(0);
+ }
if (ret < 0) {
xmlErrValidNode(ctxt, state->node,
XML_DTD_CONTENT_MODEL,
@@ -5704,6 +5673,8 @@ xmlValidatePushElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
* @data: some character data read
* @len: the length of the data
*
+ * DEPRECATED: Internal function, don't use.
+ *
* check the CData parsed for validation in the current stack
*
* returns 1 if no validation problem was found or 0 otherwise
@@ -5777,6 +5748,8 @@ xmlValidatePushCData(xmlValidCtxtPtr ctxt, const xmlChar *data, int len) {
* @elem: an element instance
* @qname: the qualified name as appearing in the serialization
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Pop the element end from the validation stack.
*
* returns 1 if no validation problem was found or 0 otherwise
@@ -5804,8 +5777,11 @@ xmlValidatePopElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc ATTRIBUTE_UNUSED,
if (state->exec != NULL) {
ret = xmlRegExecPushString(state->exec, NULL, NULL);
if (ret <= 0) {
- xmlErrValidNode(ctxt, state->node,
- XML_DTD_CONTENT_MODEL,
+ if (ret == XML_REGEXP_OUT_OF_MEMORY)
+ xmlVErrMemory(ctxt);
+ else
+ xmlErrValidNode(ctxt, state->node,
+ XML_DTD_CONTENT_MODEL,
"Element %s content does not follow the DTD, Expecting more children\n",
state->node->name, NULL,NULL);
ret = 0;
@@ -5831,6 +5807,8 @@ xmlValidatePopElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc ATTRIBUTE_UNUSED,
* @doc: a document instance
* @elem: an element instance
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Try to validate a single element and it's attributes,
* basically it does the following checks as described by the
* XML-1.0 recommendation:
@@ -5858,61 +5836,19 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
if (elem == NULL) return(0);
switch (elem->type) {
- case XML_ATTRIBUTE_NODE:
- xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
- "Attribute element not expected\n", NULL, NULL ,NULL);
- return(0);
case XML_TEXT_NODE:
- if (elem->children != NULL) {
- xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
- "Text element has children !\n",
- NULL,NULL,NULL);
- return(0);
- }
- if (elem->ns != NULL) {
- xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
- "Text element has namespace !\n",
- NULL,NULL,NULL);
- return(0);
- }
- if (elem->content == NULL) {
- xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
- "Text element has no content !\n",
- NULL,NULL,NULL);
- return(0);
- }
- return(1);
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return(1);
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
+ case XML_XINCLUDE_START:
+ case XML_XINCLUDE_END:
return(1);
- case XML_ENTITY_NODE:
- xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
- "Entity element not expected\n", NULL, NULL ,NULL);
- return(0);
- case XML_NOTATION_NODE:
- xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
- "Notation element not expected\n", NULL, NULL ,NULL);
- return(0);
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
- "Document element not expected\n", NULL, NULL ,NULL);
- return(0);
- case XML_HTML_DOCUMENT_NODE:
- xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
- "HTML Document not expected\n", NULL, NULL ,NULL);
- return(0);
case XML_ELEMENT_NODE:
break;
default:
xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
- "unknown element type\n", NULL, NULL ,NULL);
+ "unexpected element type\n", NULL, NULL ,NULL);
return(0);
}
@@ -5970,8 +5906,10 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
fullname = xmlBuildQName(child->name, child->ns->prefix,
fn, 50);
- if (fullname == NULL)
+ if (fullname == NULL) {
+ xmlVErrMemory(ctxt);
return(0);
+ }
cont = elemDecl->content;
while (cont != NULL) {
if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
@@ -6035,7 +5973,8 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
*/
child = elem->children;
while (child != NULL) {
- if (child->type == XML_TEXT_NODE) {
+ if ((child->type == XML_TEXT_NODE) &&
+ (child->content != NULL)) {
const xmlChar *content = child->content;
while (IS_BLANK_CH(*content))
@@ -6056,7 +5995,7 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
cont = elemDecl->content;
tmp = xmlValidateElementContent(ctxt, child, elemDecl, 1, elem);
if (tmp <= 0)
- ret = tmp;
+ ret = 0;
break;
}
} /* not continuous */
@@ -6198,6 +6137,8 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
* @ctxt: the validation context
* @doc: a document instance
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Try to validate a the root element
* basically it does the following check as described by the
* XML-1.0 recommendation:
@@ -6237,7 +6178,7 @@ xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
fullname = xmlBuildQName(root->name, root->ns->prefix, fn, 50);
if (fullname == NULL) {
- xmlVErrMemory(ctxt, NULL);
+ xmlVErrMemory(ctxt);
return(0);
}
ret = xmlStrEqual(doc->intSubset->name, fullname);
@@ -6291,9 +6232,13 @@ xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr root) {
attr = elem->properties;
while (attr != NULL) {
value = xmlNodeListGetString(doc, attr->children, 0);
- ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value);
- if (value != NULL)
+ if (value == NULL) {
+ xmlVErrMemory(ctxt);
+ ret = 0;
+ } else {
+ ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value);
xmlFree((char *)value);
+ }
attr= attr->next;
}
@@ -6352,7 +6297,7 @@ xmlValidateRef(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
dup = xmlStrdup(name);
if (dup == NULL) {
- ctxt->valid = 0;
+ xmlVErrMemory(ctxt);
return;
}
cur = dup;
@@ -6387,7 +6332,7 @@ xmlValidateRef(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
dup = xmlStrdup(name);
if (dup == NULL) {
- xmlVErrMemory(ctxt, "IDREFS split");
+ xmlVErrMemory(ctxt);
ctxt->valid = 0;
return;
}
@@ -6455,6 +6400,8 @@ xmlValidateCheckRefCallback(void *payload, void *data, const xmlChar *name) {
* @ctxt: the validation context
* @doc: a document instance
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Does the final step for the document validation once all the
* incremental validation steps have been completed
*
@@ -6468,7 +6415,8 @@ xmlValidateCheckRefCallback(void *payload, void *data, const xmlChar *name) {
int
xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
xmlRefTablePtr table;
- unsigned int save;
+ xmlParserCtxtPtr pctxt = NULL;
+ xmlParserInputPtr oldInput = NULL;
if (ctxt == NULL)
return(0);
@@ -6478,10 +6426,6 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
return(0);
}
- /* trick to get correct line id report */
- save = ctxt->flags;
- ctxt->flags &= ~XML_VCTXT_USE_PCTXT;
-
/*
* Check all the NOTATION/NOTATIONS attributes
*/
@@ -6491,12 +6435,24 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
/*
* Check all the IDREF/IDREFS attributes definition for validity
*/
+
+ /*
+ * Don't print line numbers.
+ */
+ if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
+ pctxt = ctxt->userData;
+ oldInput = pctxt->input;
+ pctxt->input = NULL;
+ }
+
table = (xmlRefTablePtr) doc->refs;
ctxt->doc = doc;
ctxt->valid = 1;
xmlHashScan(table, xmlValidateCheckRefCallback, ctxt);
- ctxt->flags = save;
+ if (ctxt->flags & XML_VCTXT_USE_PCTXT)
+ pctxt->input = oldInput;
+
return(ctxt->valid);
}
@@ -6522,31 +6478,42 @@ xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
xmlDtdPtr oldExt, oldInt;
xmlNodePtr root;
- if (dtd == NULL) return(0);
- if (doc == NULL) return(0);
+ if (dtd == NULL)
+ return(0);
+ if (doc == NULL)
+ return(0);
+
oldExt = doc->extSubset;
oldInt = doc->intSubset;
doc->extSubset = dtd;
doc->intSubset = NULL;
- ret = xmlValidateRoot(ctxt, doc);
- if (ret == 0) {
- doc->extSubset = oldExt;
- doc->intSubset = oldInt;
- return(ret);
- }
if (doc->ids != NULL) {
- xmlFreeIDTable(doc->ids);
- doc->ids = NULL;
+ xmlFreeIDTable(doc->ids);
+ doc->ids = NULL;
}
if (doc->refs != NULL) {
- xmlFreeRefTable(doc->refs);
- doc->refs = NULL;
+ xmlFreeRefTable(doc->refs);
+ doc->refs = NULL;
}
- root = xmlDocGetRootElement(doc);
- ret = xmlValidateElement(ctxt, doc, root);
- ret &= xmlValidateDocumentFinal(ctxt, doc);
+
+ ret = xmlValidateRoot(ctxt, doc);
+ if (ret != 0) {
+ root = xmlDocGetRootElement(doc);
+ ret = xmlValidateElement(ctxt, doc, root);
+ ret &= xmlValidateDocumentFinal(ctxt, doc);
+ }
+
doc->extSubset = oldExt;
doc->intSubset = oldInt;
+ if (doc->ids != NULL) {
+ xmlFreeIDTable(doc->ids);
+ doc->ids = NULL;
+ }
+ if (doc->refs != NULL) {
+ xmlFreeRefTable(doc->refs);
+ doc->refs = NULL;
+ }
+
return(ret);
}
@@ -6613,6 +6580,9 @@ xmlValidateAttributeCallback(void *payload, void *data,
}
}
if (cur->atype == XML_ATTRIBUTE_NOTATION) {
+ const xmlChar *elemLocalName;
+ xmlChar *elemPrefix;
+
doc = cur->doc;
if (cur->elem == NULL) {
xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
@@ -6621,13 +6591,25 @@ xmlValidateAttributeCallback(void *payload, void *data,
return;
}
- if (doc != NULL)
- elem = xmlGetDtdElementDesc(doc->intSubset, cur->elem);
- if ((elem == NULL) && (doc != NULL))
- elem = xmlGetDtdElementDesc(doc->extSubset, cur->elem);
+ elemLocalName = xmlSplitQName4(cur->elem, &elemPrefix);
+ if (elemLocalName == NULL) {
+ xmlVErrMemory(ctxt);
+ return;
+ }
+
+ if ((doc != NULL) && (doc->intSubset != NULL))
+ elem = xmlHashLookup2(doc->intSubset->elements,
+ elemLocalName, elemPrefix);
+ if ((elem == NULL) && (doc != NULL) && (doc->extSubset != NULL))
+ elem = xmlHashLookup2(doc->extSubset->elements,
+ elemLocalName, elemPrefix);
if ((elem == NULL) && (cur->parent != NULL) &&
(cur->parent->type == XML_DTD_NODE))
- elem = xmlGetDtdElementDesc((xmlDtdPtr) cur->parent, cur->elem);
+ elem = xmlHashLookup2(((xmlDtdPtr) cur->parent)->elements,
+ elemLocalName, elemPrefix);
+
+ xmlFree(elemPrefix);
+
if (elem == NULL) {
xmlErrValidNode(ctxt, NULL, XML_DTD_UNKNOWN_ELEM,
"attribute %s: could not find decl for element %s\n",
@@ -6648,6 +6630,8 @@ xmlValidateAttributeCallback(void *payload, void *data,
* @ctxt: the validation context
* @doc: a document instance
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Does the final step for the dtds validation once all the
* subsets have been parsed
*
diff --git a/win32/rcVersion.h b/win32/rcVersion.h
index abd2d71..47f1a9c 100644
--- a/win32/rcVersion.h
+++ b/win32/rcVersion.h
@@ -1,4 +1,4 @@
#define LIBXML_MAJOR_VERSION 2
-#define LIBXML_MINOR_VERSION 12
-#define LIBXML_MICRO_VERSION 8
-#define LIBXML_DOTTED_VERSION "2.12.8"
+#define LIBXML_MINOR_VERSION 13
+#define LIBXML_MICRO_VERSION 0
+#define LIBXML_DOTTED_VERSION "2.13.0"
diff --git a/xinclude.c b/xinclude.c
index b658155..7949a1c 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -49,11 +49,11 @@ typedef xmlXIncludeRef *xmlXIncludeRefPtr;
struct _xmlXIncludeRef {
xmlChar *URI; /* the fully resolved resource URL */
xmlChar *fragment; /* the fragment in the URI */
+ xmlChar *base; /* base URI of xi:include element */
xmlNodePtr elem; /* the xi:include element */
xmlNodePtr inc; /* the included copy */
int xml; /* xml or txt */
int fallback; /* fallback was loaded */
- int emptyFb; /* flag to show fallback empty */
int expanding; /* flag to detect inclusion loops */
int replace; /* should the node be replaced? */
};
@@ -89,9 +89,9 @@ struct _xmlXIncludeCtxt {
int nbErrors; /* the number of errors detected */
int fatalErr; /* abort processing */
+ int errNo; /* error code */
int legacy; /* using XINCLUDE_OLD_NS */
int parseFlags; /* the flags used for parsing XML documents */
- xmlChar * base; /* the current xml:base */
void *_private; /* application data */
@@ -100,6 +100,11 @@ struct _xmlXIncludeCtxt {
#endif
int depth; /* recursion depth */
int isStream; /* streaming mode */
+
+ xmlXPathContextPtr xpctxt;
+
+ xmlStructuredErrorFunc errorHandler;
+ void *errorCtxt;
};
static xmlXIncludeRefPtr
@@ -125,15 +130,14 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree);
* Handle an out of memory condition
*/
static void
-xmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node,
- const char *extra)
+xmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt)
{
- if (ctxt != NULL)
- ctxt->nbErrors++;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
- XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
- extra, NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
+ ctxt->errNo = XML_ERR_NO_MEMORY;
+ ctxt->fatalErr = 1;
+ ctxt->nbErrors++;
+
+ xmlRaiseMemoryError(ctxt->errorHandler, NULL, ctxt->errorCtxt,
+ XML_FROM_XINCLUDE, NULL);
}
/**
@@ -149,34 +153,34 @@ static void LIBXML_ATTR_FORMAT(4,0)
xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
const char *msg, const xmlChar *extra)
{
- if (ctxt != NULL)
- ctxt->nbErrors++;
- __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
- error, XML_ERR_ERROR, NULL, 0,
- (const char *) extra, NULL, NULL, 0, 0,
- msg, (const char *) extra);
-}
+ xmlStructuredErrorFunc schannel = NULL;
+ xmlGenericErrorFunc channel = NULL;
+ void *data = NULL;
+ int res;
-#if 0
-/**
- * xmlXIncludeWarn:
- * @ctxt: the XInclude context
- * @node: the context node
- * @msg: the error message
- * @extra: extra information
- *
- * Emit an XInclude warning.
- */
-static void LIBXML_ATTR_FORMAT(4,0)
-xmlXIncludeWarn(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
- const char *msg, const xmlChar *extra)
-{
- __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
- error, XML_ERR_WARNING, NULL, 0,
- (const char *) extra, NULL, NULL, 0, 0,
- msg, (const char *) extra);
+ if (ctxt->fatalErr != 0)
+ return;
+ ctxt->nbErrors++;
+
+ schannel = ctxt->errorHandler;
+ data = ctxt->errorCtxt;
+
+ if (schannel == NULL) {
+ channel = xmlGenericError;
+ data = xmlGenericErrorContext;
+ }
+
+ res = __xmlRaiseError(schannel, channel, data, ctxt, node,
+ XML_FROM_XINCLUDE, error, XML_ERR_ERROR,
+ NULL, 0, (const char *) extra, NULL, NULL, 0, 0,
+ msg, (const char *) extra);
+ if (res < 0) {
+ ctxt->errNo = XML_ERR_NO_MEMORY;
+ ctxt->fatalErr = 1;
+ } else {
+ ctxt->errNo = error;
+ }
}
-#endif
/**
* xmlXIncludeGetProp:
@@ -193,15 +197,20 @@ xmlXIncludeGetProp(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur,
const xmlChar *name) {
xmlChar *ret;
- ret = xmlGetNsProp(cur, XINCLUDE_NS, name);
+ if (xmlNodeGetAttrValue(cur, name, XINCLUDE_NS, &ret) < 0)
+ xmlXIncludeErrMemory(ctxt);
if (ret != NULL)
return(ret);
+
if (ctxt->legacy != 0) {
- ret = xmlGetNsProp(cur, XINCLUDE_OLD_NS, name);
- if (ret != NULL)
- return(ret);
+ if (xmlNodeGetAttrValue(cur, name, XINCLUDE_OLD_NS, &ret) < 0)
+ xmlXIncludeErrMemory(ctxt);
+ if (ret != NULL)
+ return(ret);
}
- ret = xmlGetProp(cur, name);
+
+ if (xmlNodeGetAttrValue(cur, name, NULL, &ret) < 0)
+ xmlXIncludeErrMemory(ctxt);
return(ret);
}
/**
@@ -218,60 +227,11 @@ xmlXIncludeFreeRef(xmlXIncludeRefPtr ref) {
xmlFree(ref->URI);
if (ref->fragment != NULL)
xmlFree(ref->fragment);
+ if (ref->base != NULL)
+ xmlFree(ref->base);
xmlFree(ref);
}
-/**
- * xmlXIncludeNewRef:
- * @ctxt: the XInclude context
- * @URI: the resource URI
- * @elem: the xi:include element
- *
- * Creates a new reference within an XInclude context
- *
- * Returns the new set
- */
-static xmlXIncludeRefPtr
-xmlXIncludeNewRef(xmlXIncludeCtxtPtr ctxt, const xmlChar *URI,
- xmlNodePtr elem) {
- xmlXIncludeRefPtr ret;
-
- ret = (xmlXIncludeRefPtr) xmlMalloc(sizeof(xmlXIncludeRef));
- if (ret == NULL) {
- xmlXIncludeErrMemory(ctxt, elem, "growing XInclude context");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlXIncludeRef));
- if (URI == NULL)
- ret->URI = NULL;
- else
- ret->URI = xmlStrdup(URI);
- ret->fragment = NULL;
- ret->elem = elem;
- ret->xml = 0;
- ret->inc = NULL;
- if (ctxt->incNr >= ctxt->incMax) {
- xmlXIncludeRefPtr *tmp;
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
- size_t newSize = ctxt->incMax ? ctxt->incMax * 2 : 1;
-#else
- size_t newSize = ctxt->incMax ? ctxt->incMax * 2 : 4;
-#endif
-
- tmp = (xmlXIncludeRefPtr *) xmlRealloc(ctxt->incTab,
- newSize * sizeof(ctxt->incTab[0]));
- if (tmp == NULL) {
- xmlXIncludeErrMemory(ctxt, elem, "growing XInclude context");
- xmlXIncludeFreeRef(ret);
- return(NULL);
- }
- ctxt->incTab = tmp;
- ctxt->incMax = newSize;
- }
- ctxt->incTab[ctxt->incNr++] = ret;
- return(ret);
-}
-
/**
* xmlXIncludeNewContext:
* @doc: an XML Document
@@ -287,11 +247,8 @@ xmlXIncludeNewContext(xmlDocPtr doc) {
if (doc == NULL)
return(NULL);
ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
- if (ret == NULL) {
- xmlXIncludeErrMemory(NULL, (xmlNodePtr) doc,
- "creating XInclude context");
+ if (ret == NULL)
return(NULL);
- }
memset(ret, 0, sizeof(xmlXIncludeCtxt));
ret->doc = doc;
ret->incNr = 0;
@@ -333,9 +290,8 @@ xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
}
xmlFree(ctxt->txtTab);
}
- if (ctxt->base != NULL) {
- xmlFree(ctxt->base);
- }
+ if (ctxt->xpctxt != NULL)
+ xmlXPathFreeContext(ctxt->xpctxt);
xmlFree(ctxt);
}
@@ -348,7 +304,7 @@ xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
*/
static xmlDocPtr
xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
- xmlDocPtr ret;
+ xmlDocPtr ret = NULL;
xmlParserCtxtPtr pctxt;
xmlParserInputPtr inputStream;
@@ -356,9 +312,11 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
pctxt = xmlNewParserCtxt();
if (pctxt == NULL) {
- xmlXIncludeErrMemory(ctxt, NULL, "cannot allocate parser context");
+ xmlXIncludeErrMemory(ctxt);
return(NULL);
}
+ if (ctxt->errorHandler != NULL)
+ xmlCtxtSetErrorHandler(pctxt, ctxt->errorHandler, ctxt->errorCtxt);
/*
* pass in the application data to the parser context.
@@ -376,25 +334,14 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
xmlDictReference(pctxt->dict);
}
- xmlCtxtUseOptions(pctxt, ctxt->parseFlags | XML_PARSE_DTDLOAD);
-
- /* Don't read from stdin. */
- if ((URL != NULL) && (strcmp(URL, "-") == 0))
- URL = "./-";
+ xmlCtxtUseOptions(pctxt, ctxt->parseFlags);
inputStream = xmlLoadExternalEntity(URL, NULL, pctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(pctxt);
- return(NULL);
- }
+ if (inputStream == NULL)
+ goto error;
inputPush(pctxt, inputStream);
- if (pctxt->directory == NULL)
- pctxt->directory = xmlParserGetDirectory(URL);
-
- pctxt->loadsubset |= XML_DETECT_IDS;
-
xmlParseDocument(pctxt);
if (pctxt->wellFormed) {
@@ -406,6 +353,10 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
xmlFreeDoc(pctxt->myDoc);
pctxt->myDoc = NULL;
}
+
+error:
+ if (pctxt->errNo == XML_ERR_NO_MEMORY)
+ xmlXIncludeErrMemory(ctxt);
xmlFreeParserCtxt(pctxt);
return(ret);
@@ -420,17 +371,17 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
*/
static xmlXIncludeRefPtr
xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
- xmlXIncludeRefPtr ref;
- xmlURIPtr uri;
- xmlChar *URL;
+ xmlXIncludeRefPtr ref = NULL;
+ xmlXIncludeRefPtr ret = NULL;
+ xmlURIPtr uri = NULL;
+ xmlChar *href = NULL;
+ xmlChar *parse = NULL;
xmlChar *fragment = NULL;
- xmlChar *href;
- xmlChar *parse;
- xmlChar *base;
- xmlChar *URI;
+ xmlChar *base = NULL;
+ xmlChar *tmp;
int xml = 1;
int local = 0;
-
+ int res;
if (ctxt == NULL)
return(NULL);
@@ -440,12 +391,24 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
/*
* read the attributes
*/
+
+ fragment = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE_XPOINTER);
+
href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
if (href == NULL) {
+ if (fragment == NULL) {
+ xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_NO_HREF,
+ "href or xpointer must be present\n", parse);
+ goto error;
+ }
+
href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
- if (href == NULL)
- return(NULL);
+ if (href == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
+ }
}
+
parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
if (parse != NULL) {
if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
@@ -455,61 +418,21 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
else {
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_PARSE_VALUE,
"invalid value %s for 'parse'\n", parse);
- if (href != NULL)
- xmlFree(href);
- if (parse != NULL)
- xmlFree(parse);
- return(NULL);
+ goto error;
}
}
- /*
- * compute the URI
- */
- base = xmlNodeGetBase(ctxt->doc, cur);
- if (base == NULL) {
- URI = xmlBuildURI(href, ctxt->doc->URL);
- } else {
- URI = xmlBuildURI(href, base);
- }
- if (URI == NULL) {
- xmlChar *escbase;
- xmlChar *eschref;
- /*
- * Some escaping may be needed
- */
- escbase = xmlURIEscape(base);
- eschref = xmlURIEscape(href);
- URI = xmlBuildURI(eschref, escbase);
- if (escbase != NULL)
- xmlFree(escbase);
- if (eschref != NULL)
- xmlFree(eschref);
- }
- if (parse != NULL)
- xmlFree(parse);
- if (href != NULL)
- xmlFree(href);
- if (base != NULL)
- xmlFree(base);
- if (URI == NULL) {
- xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
- "failed build URL\n", NULL);
- return(NULL);
- }
- fragment = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE_XPOINTER);
-
/*
* Check the URL and remove any fragment identifier
*/
- uri = xmlParseURI((const char *)URI);
+ res = xmlParseURISafe((const char *)href, &uri);
if (uri == NULL) {
- xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
- "invalid value URI %s\n", URI);
- if (fragment != NULL)
- xmlFree(fragment);
- xmlFree(URI);
- return(NULL);
+ if (res < 0)
+ xmlXIncludeErrMemory(ctxt);
+ else
+ xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
+ "invalid value href %s\n", href);
+ goto error;
}
if (uri->fragment != NULL) {
@@ -522,29 +445,46 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
} else {
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_FRAGMENT_ID,
"Invalid fragment identifier in URI %s use the xpointer attribute\n",
- URI);
- if (fragment != NULL)
- xmlFree(fragment);
- xmlFreeURI(uri);
- xmlFree(URI);
- return(NULL);
+ href);
+ goto error;
}
uri->fragment = NULL;
}
- URL = xmlSaveUri(uri);
- xmlFreeURI(uri);
- if (URL == NULL) {
- xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
- "invalid value URI %s\n", URI);
- if (fragment != NULL)
- xmlFree(fragment);
- xmlFree(URI);
- return(NULL);
+ tmp = xmlSaveUri(uri);
+ if (tmp == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
+ }
+ xmlFree(href);
+ href = tmp;
+
+ /*
+ * Resolve URI
+ */
+
+ if (xmlNodeGetBaseSafe(ctxt->doc, cur, &base) < 0) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
}
- xmlFree(URI);
- if (xmlStrEqual(URL, ctxt->doc->URL))
- local = 1;
+ if (href[0] != 0) {
+ if (xmlBuildURISafe(href, base, &tmp) < 0) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
+ }
+ if (tmp == NULL) {
+ xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
+ "failed build URL\n", NULL);
+ goto error;
+ }
+ xmlFree(href);
+ href = tmp;
+
+ if (xmlStrEqual(href, ctxt->doc->URL))
+ local = 1;
+ } else {
+ local = 1;
+ }
/*
* If local and xml then we need a fragment
@@ -553,21 +493,72 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
((fragment == NULL) || (fragment[0] == 0))) {
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_RECURSION,
"detected a local recursion with no xpointer in %s\n",
- URL);
- xmlFree(URL);
- xmlFree(fragment);
- return(NULL);
+ href);
+ goto error;
}
- ref = xmlXIncludeNewRef(ctxt, URL, cur);
- xmlFree(URL);
+ ref = (xmlXIncludeRefPtr) xmlMalloc(sizeof(xmlXIncludeRef));
if (ref == NULL) {
- xmlFree(fragment);
- return(NULL);
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
}
- ref->fragment = fragment;
+ memset(ref, 0, sizeof(xmlXIncludeRef));
+
+ ref->elem = cur;
ref->xml = xml;
- return(ref);
+ ref->URI = href;
+ href = NULL;
+ ref->fragment = fragment;
+ fragment = NULL;
+
+ /*
+ * xml:base fixup
+ */
+ if (((ctxt->parseFlags & XML_PARSE_NOBASEFIX) == 0) &&
+ (cur->doc != NULL) &&
+ ((cur->doc->parseFlags & XML_PARSE_NOBASEFIX) == 0)) {
+ if (base != NULL) {
+ ref->base = base;
+ base = NULL;
+ } else {
+ ref->base = xmlStrdup(BAD_CAST "");
+ if (ref->base == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
+ }
+ }
+ }
+
+ if (ctxt->incNr >= ctxt->incMax) {
+ xmlXIncludeRefPtr *table;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ size_t newSize = ctxt->incMax ? ctxt->incMax * 2 : 1;
+#else
+ size_t newSize = ctxt->incMax ? ctxt->incMax * 2 : 4;
+#endif
+
+ table = (xmlXIncludeRefPtr *) xmlRealloc(ctxt->incTab,
+ newSize * sizeof(ctxt->incTab[0]));
+ if (table == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
+ }
+ ctxt->incTab = table;
+ ctxt->incMax = newSize;
+ }
+ ctxt->incTab[ctxt->incNr++] = ref;
+
+ ret = ref;
+ ref = NULL;
+
+error:
+ xmlXIncludeFreeRef(ref);
+ xmlFreeURI(uri);
+ xmlFree(href);
+ xmlFree(parse);
+ xmlFree(fragment);
+ xmlFree(base);
+ return(ret);
}
/**
@@ -579,8 +570,7 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
* The XInclude recursive nature is handled at this point.
*/
static void
-xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
- const xmlURL url ATTRIBUTE_UNUSED) {
+xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc) {
xmlDocPtr oldDoc;
xmlXIncludeRefPtr *oldIncTab;
int oldIncMax, oldIncNr, oldIsStream;
@@ -618,6 +608,56 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
* *
************************************************************************/
+static void
+xmlXIncludeBaseFixup(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur, xmlNodePtr copy,
+ const xmlChar *targetBase) {
+ xmlChar *base = NULL;
+ xmlChar *relBase = NULL;
+ xmlNs ns;
+ int res;
+
+ if (cur->type != XML_ELEMENT_NODE)
+ return;
+
+ if (xmlNodeGetBaseSafe(cur->doc, cur, &base) < 0)
+ xmlXIncludeErrMemory(ctxt);
+
+ if ((base != NULL) && !xmlStrEqual(base, targetBase)) {
+ if (xmlBuildRelativeURISafe(base, targetBase, &relBase) < 0) {
+ xmlXIncludeErrMemory(ctxt);
+ goto done;
+ }
+ if (relBase == NULL) {
+ xmlXIncludeErr(ctxt, cur,
+ XML_XINCLUDE_HREF_URI,
+ "Building relative URI failed: %s\n",
+ base);
+ goto done;
+ }
+
+ /*
+ * If the new base doesn't contain a slash, it can be omitted.
+ */
+ if (xmlStrchr(relBase, '/') != NULL) {
+ res = xmlNodeSetBase(copy, relBase);
+ if (res < 0)
+ xmlXIncludeErrMemory(ctxt);
+ goto done;
+ }
+ }
+
+ /*
+ * Delete existing xml:base if bases are equal
+ */
+ memset(&ns, 0, sizeof(ns));
+ ns.href = XML_XML_NAMESPACE;
+ xmlUnsetNsProp(copy, &ns, BAD_CAST "base");
+
+done:
+ xmlFree(base);
+ xmlFree(relBase);
+}
+
/**
* xmlXIncludeCopyNode:
* @ctxt: the XInclude context
@@ -630,11 +670,13 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
*/
static xmlNodePtr
xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr elem,
- int copyChildren) {
+ int copyChildren, const xmlChar *targetBase) {
xmlNodePtr result = NULL;
xmlNodePtr insertParent = NULL;
xmlNodePtr insertLast = NULL;
xmlNodePtr cur;
+ xmlNodePtr item;
+ int depth = 0;
if (copyChildren) {
cur = elem->children;
@@ -663,22 +705,33 @@ xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr elem,
/*
* TODO: Insert XML_XINCLUDE_START and XML_XINCLUDE_END nodes
*/
- if (ref->inc != NULL) {
- copy = xmlStaticCopyNodeList(ref->inc, ctxt->doc,
- insertParent);
- if (copy == NULL)
+ for (item = ref->inc; item != NULL; item = item->next) {
+ copy = xmlStaticCopyNode(item, ctxt->doc, insertParent, 1);
+ if (copy == NULL) {
+ xmlXIncludeErrMemory(ctxt);
goto error;
+ }
+
+ if (result == NULL)
+ result = copy;
+ if (insertLast != NULL) {
+ insertLast->next = copy;
+ copy->prev = insertLast;
+ } else if (insertParent != NULL) {
+ insertParent->children = copy;
+ }
+ insertLast = copy;
+
+ if ((depth == 0) && (targetBase != NULL))
+ xmlXIncludeBaseFixup(ctxt, item, copy, targetBase);
}
} else {
copy = xmlStaticCopyNode(cur, ctxt->doc, insertParent, 2);
- if (copy == NULL)
+ if (copy == NULL) {
+ xmlXIncludeErrMemory(ctxt);
goto error;
+ }
- recurse = (cur->type != XML_ENTITY_REF_NODE) &&
- (cur->children != NULL);
- }
-
- if (copy != NULL) {
if (result == NULL)
result = copy;
if (insertLast != NULL) {
@@ -688,15 +741,19 @@ xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr elem,
insertParent->children = copy;
}
insertLast = copy;
- while (insertLast->next != NULL) {
- insertLast = insertLast->next;
- }
+
+ if ((depth == 0) && (targetBase != NULL))
+ xmlXIncludeBaseFixup(ctxt, cur, copy, targetBase);
+
+ recurse = (cur->type != XML_ENTITY_REF_NODE) &&
+ (cur->children != NULL);
}
if (recurse) {
cur = cur->children;
insertParent = insertLast;
insertLast = NULL;
+ depth += 1;
continue;
}
@@ -711,6 +768,7 @@ xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr elem,
return(result);
insertLast = insertParent;
insertParent = insertParent->parent;
+ depth -= 1;
}
cur = cur->next;
@@ -959,6 +1017,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr range) {
}
#endif /* LIBXML_XPTR_LOCS_ENABLED */
+#ifdef LIBXML_XPTR_ENABLED
/**
* xmlXIncludeCopyXPointer:
* @ctxt: the XInclude context
@@ -971,7 +1030,8 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr range) {
* the caller has to free the node tree.
*/
static xmlNodePtr
-xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr obj) {
+xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr obj,
+ const xmlChar *targetBase) {
xmlNodePtr list = NULL, last = NULL, copy;
int i;
@@ -981,7 +1041,7 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr obj) {
case XPATH_NODESET: {
xmlNodeSetPtr set = obj->nodesetval;
if (set == NULL)
- return(NULL);
+ break;
for (i = 0;i < set->nodeNr;i++) {
xmlNodePtr node;
@@ -995,11 +1055,11 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr obj) {
if (node == NULL) {
xmlXIncludeErr(ctxt, set->nodeTab[i],
XML_ERR_INTERNAL_ERROR,
- "document without root\n", NULL);
+ "document without root\n", NULL);
continue;
}
break;
- case XML_TEXT_NODE:
+ case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ELEMENT_NODE:
case XML_PI_NODE:
@@ -1019,7 +1079,7 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr obj) {
* xmlXIncludeCopyNode is only required for the initial
* document.
*/
- copy = xmlXIncludeCopyNode(ctxt, node, 0);
+ copy = xmlXIncludeCopyNode(ctxt, node, 0, targetBase);
if (copy == NULL) {
xmlFreeNodeList(list);
return(NULL);
@@ -1044,10 +1104,12 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr obj) {
for (i = 0;i < set->locNr;i++) {
if (last == NULL)
list = last = xmlXIncludeCopyXPointer(ctxt,
- set->locTab[i]);
+ set->locTab[i],
+ targetBase);
else
xmlAddNextSibling(last,
- xmlXIncludeCopyXPointer(ctxt, set->locTab[i]));
+ xmlXIncludeCopyXPointer(ctxt, set->locTab[i],
+ targetBase));
if (last != NULL) {
while (last->next != NULL)
last = last->next;
@@ -1066,6 +1128,8 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr obj) {
}
return(list);
}
+#endif
+
/************************************************************************
* *
* XInclude I/O handling *
@@ -1112,32 +1176,36 @@ xmlXIncludeMergeEntity(void *payload, void *vdata,
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
break;
}
- ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID,
- ent->SystemID, ent->content);
- if (ret != NULL) {
- if (ent->URI != NULL)
+ prev = xmlGetDocEntity(doc, ent->name);
+ if (prev == NULL) {
+ ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID,
+ ent->SystemID, ent->content);
+ if (ret == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ return;
+ }
+ if (ent->URI != NULL) {
ret->URI = xmlStrdup(ent->URI);
+ if (ret->URI == 0)
+ xmlXIncludeErrMemory(ctxt);
+ }
} else {
- prev = xmlGetDocEntity(doc, ent->name);
- if (prev != NULL) {
- if (ent->etype != prev->etype)
- goto error;
-
- if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
- if (!xmlStrEqual(ent->SystemID, prev->SystemID))
- goto error;
- } else if ((ent->ExternalID != NULL) &&
- (prev->ExternalID != NULL)) {
- if (!xmlStrEqual(ent->ExternalID, prev->ExternalID))
- goto error;
- } else if ((ent->content != NULL) && (prev->content != NULL)) {
- if (!xmlStrEqual(ent->content, prev->content))
- goto error;
- } else {
- goto error;
- }
+ if (ent->etype != prev->etype)
+ goto error;
- }
+ if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
+ if (!xmlStrEqual(ent->SystemID, prev->SystemID))
+ goto error;
+ } else if ((ent->ExternalID != NULL) &&
+ (prev->ExternalID != NULL)) {
+ if (!xmlStrEqual(ent->ExternalID, prev->ExternalID))
+ goto error;
+ } else if ((ent->content != NULL) && (prev->content != NULL)) {
+ if (!xmlStrEqual(ent->content, prev->content))
+ goto error;
+ } else {
+ goto error;
+ }
}
return;
error:
@@ -1184,8 +1252,10 @@ xmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
if (cur == NULL)
return(-1);
target = xmlCreateIntSubset(doc, cur->name, NULL, NULL);
- if (target == NULL)
+ if (target == NULL) {
+ xmlXIncludeErrMemory(ctxt);
return(-1);
+ }
}
source = from->intSubset;
@@ -1228,13 +1298,11 @@ xmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
* Returns 0 in case of success, -1 in case of failure
*/
static int
-xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
- xmlXIncludeRefPtr ref) {
+xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
xmlXIncludeDocPtr cache;
xmlDocPtr doc;
- xmlURIPtr uri;
- xmlChar *URL = NULL;
- xmlChar *fragment = NULL;
+ const xmlChar *url = ref->URI;
+ const xmlChar *fragment = ref->fragment;
int i = 0;
int ret = -1;
int cacheNr;
@@ -1242,37 +1310,12 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
int saveFlags;
#endif
- /*
- * Check the URL and remove any fragment identifier
- */
- uri = xmlParseURI((const char *)url);
- if (uri == NULL) {
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
- "invalid value URI %s\n", url);
- goto error;
- }
- if (uri->fragment != NULL) {
- fragment = (xmlChar *) uri->fragment;
- uri->fragment = NULL;
- }
- if (ref->fragment != NULL) {
- if (fragment != NULL) xmlFree(fragment);
- fragment = xmlStrdup(ref->fragment);
- }
- URL = xmlSaveUri(uri);
- xmlFreeURI(uri);
- if (URL == NULL) {
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
- "invalid value URI %s\n", url);
- goto error;
- }
-
/*
* Handling of references to the local document are done
* directly through ctxt->doc.
*/
- if ((URL[0] == 0) || (URL[0] == '#') ||
- ((ctxt->doc != NULL) && (xmlStrEqual(URL, ctxt->doc->URL)))) {
+ if ((url[0] == 0) || (url[0] == '#') ||
+ ((ctxt->doc != NULL) && (xmlStrEqual(url, ctxt->doc->URL)))) {
doc = ctxt->doc;
goto loaded;
}
@@ -1281,7 +1324,7 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
* Prevent reloading the document twice.
*/
for (i = 0; i < ctxt->urlNr; i++) {
- if (xmlStrEqual(URL, ctxt->urlTab[i].url)) {
+ if (xmlStrEqual(url, ctxt->urlTab[i].url)) {
if (ctxt->urlTab[i].expanding) {
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_RECURSION,
"inclusion loop detected\n", NULL);
@@ -1309,7 +1352,7 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
}
#endif
- doc = xmlXIncludeParseFile(ctxt, (const char *)URL);
+ doc = xmlXIncludeParseFile(ctxt, (const char *)url);
#ifdef LIBXML_XPTR_ENABLED
ctxt->parseFlags = saveFlags;
#endif
@@ -1325,19 +1368,23 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
tmp = xmlRealloc(ctxt->urlTab, sizeof(xmlXIncludeDoc) * newSize);
if (tmp == NULL) {
- xmlXIncludeErrMemory(ctxt, ref->elem,
- "growing XInclude URL table");
+ xmlXIncludeErrMemory(ctxt);
xmlFreeDoc(doc);
goto error;
}
ctxt->urlMax = newSize;
ctxt->urlTab = tmp;
}
- cacheNr = ctxt->urlNr++;
- cache = &ctxt->urlTab[cacheNr];
+ cache = &ctxt->urlTab[ctxt->urlNr];
cache->doc = doc;
- cache->url = xmlStrdup(URL);
+ cache->url = xmlStrdup(url);
+ if (cache->url == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ xmlFreeDoc(doc);
+ goto error;
+ }
cache->expanding = 0;
+ cacheNr = ctxt->urlNr++;
if (doc == NULL)
goto error;
@@ -1347,10 +1394,8 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
* To check for this, we compare the URL with that of the doc
* and change it if they disagree (bug 146988).
*/
- if (!xmlStrEqual(URL, doc->URL)) {
- xmlFree(URL);
- URL = xmlStrdup(doc->URL);
- }
+ if ((doc->URL != NULL) && (!xmlStrEqual(url, doc->URL)))
+ url = doc->URL;
/*
* Make sure we have all entities fixed up
@@ -1371,17 +1416,30 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
}
*/
cache->expanding = 1;
- xmlXIncludeRecurseDoc(ctxt, doc, URL);
+ xmlXIncludeRecurseDoc(ctxt, doc);
/* urlTab might be reallocated. */
cache = &ctxt->urlTab[cacheNr];
cache->expanding = 0;
loaded:
if (fragment == NULL) {
- /*
- * Add the top children list as the replacement copy.
- */
- ref->inc = xmlDocCopyNode(xmlDocGetRootElement(doc), ctxt->doc, 1);
+ xmlNodePtr root;
+
+ root = xmlDocGetRootElement(doc);
+ if (root == NULL) {
+ xmlXIncludeErr(ctxt, ref->elem, XML_ERR_INTERNAL_ERROR,
+ "document without root\n", NULL);
+ goto error;
+ }
+
+ ref->inc = xmlDocCopyNode(root, ctxt->doc, 1);
+ if (ref->inc == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
+ }
+
+ if (ref->base != NULL)
+ xmlXIncludeBaseFixup(ctxt, root, ref->inc, ref->base);
}
#ifdef LIBXML_XPTR_ENABLED
else {
@@ -1390,7 +1448,6 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
* as the replacement copy.
*/
xmlXPathObjectPtr xptr;
- xmlXPathContextPtr xptrctxt;
xmlNodeSetPtr set;
if (ctxt->isStream && doc == ctxt->doc) {
@@ -1400,18 +1457,27 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
goto error;
}
- xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
- if (xptrctxt == NULL) {
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_XPTR_FAILED,
- "could not create XPointer context\n", NULL);
- goto error;
- }
- xptr = xmlXPtrEval(fragment, xptrctxt);
+ if (ctxt->xpctxt == NULL) {
+ ctxt->xpctxt = xmlXPtrNewContext(doc, NULL, NULL);
+ if (ctxt->xpctxt == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
+ }
+ if (ctxt->errorHandler != NULL)
+ xmlXPathSetErrorHandler(ctxt->xpctxt, ctxt->errorHandler,
+ ctxt->errorCtxt);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ ctxt->xpctxt->opLimit = 100000;
+#endif
+ }
+ xptr = xmlXPtrEval(fragment, ctxt->xpctxt);
if (xptr == NULL) {
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_XPTR_FAILED,
- "XPointer evaluation failed: #%s\n",
- fragment);
- xmlXPathFreeContext(xptrctxt);
+ if (ctxt->xpctxt->lastError.code == XML_ERR_NO_MEMORY)
+ xmlXIncludeErrMemory(ctxt);
+ else
+ xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_XPTR_FAILED,
+ "XPointer evaluation failed: #%s\n",
+ fragment);
goto error;
}
switch (xptr->type) {
@@ -1428,15 +1494,9 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
"XPointer is not a range: #%s\n",
fragment);
xmlXPathFreeObject(xptr);
- xmlXPathFreeContext(xptrctxt);
goto error;
case XPATH_NODESET:
- if ((xptr->nodesetval == NULL) ||
- (xptr->nodesetval->nodeNr <= 0)) {
- xmlXPathFreeObject(xptr);
- xmlXPathFreeContext(xptrctxt);
- goto error;
- }
+ break;
#ifdef LIBXML_XPTR_LOCS_ENABLED
case XPATH_RANGE:
@@ -1494,106 +1554,20 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
}
}
}
- ref->inc = xmlXIncludeCopyXPointer(ctxt, xptr);
+ ref->inc = xmlXIncludeCopyXPointer(ctxt, xptr, ref->base);
xmlXPathFreeObject(xptr);
- xmlXPathFreeContext(xptrctxt);
}
#endif
- /*
- * Do the xml:base fixup if needed
- */
- if ((doc != NULL) && (URL != NULL) &&
- (!(ctxt->parseFlags & XML_PARSE_NOBASEFIX)) &&
- (!(doc->parseFlags & XML_PARSE_NOBASEFIX))) {
- xmlNodePtr node;
- xmlChar *base;
- xmlChar *curBase;
-
- /*
- * The base is only adjusted if "necessary", i.e. if the xinclude node
- * has a base specified, or the URL is relative
- */
- base = xmlGetNsProp(ref->elem, BAD_CAST "base", XML_XML_NAMESPACE);
- if (base == NULL) {
- /*
- * No xml:base on the xinclude node, so we check whether the
- * URI base is different than (relative to) the context base
- */
- curBase = xmlBuildRelativeURI(URL, ctxt->base);
- if (curBase == NULL) { /* Error return */
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
- "trying to build relative URI from %s\n", URL);
- } else {
- /* If the URI doesn't contain a slash, it's not relative */
- if (!xmlStrchr(curBase, '/'))
- xmlFree(curBase);
- else
- base = curBase;
- }
- }
- if (base != NULL) { /* Adjustment may be needed */
- node = ref->inc;
- while (node != NULL) {
- /* Only work on element nodes */
- if (node->type == XML_ELEMENT_NODE) {
- curBase = xmlNodeGetBase(node->doc, node);
- /* If no current base, set it */
- if (curBase == NULL) {
- xmlNodeSetBase(node, base);
- } else {
- /*
- * If the current base is the same as the
- * URL of the document, then reset it to be
- * the specified xml:base or the relative URI
- */
- if (xmlStrEqual(curBase, node->doc->URL)) {
- xmlNodeSetBase(node, base);
- } else {
- /*
- * If the element already has an xml:base
- * set, then relativise it if necessary
- */
- xmlChar *xmlBase;
- xmlBase = xmlGetNsProp(node,
- BAD_CAST "base",
- XML_XML_NAMESPACE);
- if (xmlBase != NULL) {
- xmlChar *relBase;
- relBase = xmlBuildURI(xmlBase, base);
- if (relBase == NULL) { /* error */
- xmlXIncludeErr(ctxt,
- ref->elem,
- XML_XINCLUDE_HREF_URI,
- "trying to rebuild base from %s\n",
- xmlBase);
- } else {
- xmlNodeSetBase(node, relBase);
- xmlFree(relBase);
- }
- xmlFree(xmlBase);
- }
- }
- xmlFree(curBase);
- }
- }
- node = node->next;
- }
- xmlFree(base);
- }
- }
ret = 0;
error:
- xmlFree(URL);
- xmlFree(fragment);
return(ret);
}
/**
* xmlXIncludeLoadTxt:
* @ctxt: the XInclude context
- * @url: the associated URL
* @ref: an XMLXincludeRefPtr
*
* Load the content, and store the result in the XInclude context
@@ -1601,53 +1575,25 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
* Returns 0 in case of success, -1 in case of failure
*/
static int
-xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
- xmlXIncludeRefPtr ref) {
+xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
xmlParserInputBufferPtr buf;
xmlNodePtr node = NULL;
- xmlURIPtr uri = NULL;
- xmlChar *URL = NULL;
+ const xmlChar *url = ref->URI;
int i;
int ret = -1;
xmlChar *encoding = NULL;
- xmlCharEncoding enc = (xmlCharEncoding) 0;
+ xmlCharEncodingHandlerPtr handler = NULL;
xmlParserCtxtPtr pctxt = NULL;
xmlParserInputPtr inputStream = NULL;
int len;
+ int res;
const xmlChar *content;
-
- /* Don't read from stdin. */
- if (xmlStrcmp(url, BAD_CAST "-") == 0)
- url = BAD_CAST "./-";
-
- /*
- * Check the URL and remove any fragment identifier
- */
- uri = xmlParseURI((const char *)url);
- if (uri == NULL) {
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
- "invalid value URI %s\n", url);
- goto error;
- }
- if (uri->fragment != NULL) {
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_TEXT_FRAGMENT,
- "fragment identifier forbidden for text: %s\n",
- (const xmlChar *) uri->fragment);
- goto error;
- }
- URL = xmlSaveUri(uri);
- if (URL == NULL) {
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
- "invalid value URI %s\n", url);
- goto error;
- }
-
/*
* Handling of references to the local document are done
* directly through ctxt->doc.
*/
- if (URL[0] == 0) {
+ if (url[0] == 0) {
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_TEXT_DOCUMENT,
"text serialization of document not available\n", NULL);
goto error;
@@ -1657,8 +1603,10 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
* Prevent reloading the document twice.
*/
for (i = 0; i < ctxt->txtNr; i++) {
- if (xmlStrEqual(URL, ctxt->txtTab[i].url)) {
+ if (xmlStrEqual(url, ctxt->txtTab[i].url)) {
node = xmlNewDocText(ctxt->doc, ctxt->txtTab[i].text);
+ if (node == NULL)
+ xmlXIncludeErrMemory(ctxt);
goto loaded;
}
}
@@ -1667,47 +1615,70 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
* Try to get the encoding if available
*/
if (ref->elem != NULL) {
- encoding = xmlGetProp(ref->elem, XINCLUDE_PARSE_ENCODING);
+ encoding = xmlXIncludeGetProp(ctxt, ref->elem, XINCLUDE_PARSE_ENCODING);
}
if (encoding != NULL) {
- /*
- * TODO: we should not have to remap to the xmlCharEncoding
- * predefined set, a better interface than
- * xmlParserInputBufferCreateFilename should allow any
- * encoding supported by iconv
- */
- enc = xmlParseCharEncoding((const char *) encoding);
- if (enc == XML_CHAR_ENCODING_ERROR) {
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_UNKNOWN_ENCODING,
- "encoding %s not supported\n", encoding);
- goto error;
- }
+ res = xmlOpenCharEncodingHandler((const char *) encoding,
+ /* output */ 0, &handler);
+
+ if (res != 0) {
+ if (res == XML_ERR_NO_MEMORY) {
+ xmlXIncludeErrMemory(ctxt);
+ } else if (res == XML_ERR_UNSUPPORTED_ENCODING) {
+ xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_UNKNOWN_ENCODING,
+ "encoding %s not supported\n", encoding);
+ goto error;
+ } else {
+ xmlXIncludeErr(ctxt, ref->elem, res,
+ "unexpected error from iconv or ICU\n", NULL);
+ goto error;
+ }
+ }
}
/*
* Load it.
*/
pctxt = xmlNewParserCtxt();
- inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
- if(inputStream == NULL)
+ if (pctxt == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
+ }
+ inputStream = xmlLoadExternalEntity((const char*)url, NULL, pctxt);
+ if (inputStream == NULL) {
+ if (pctxt->errNo == XML_ERR_NO_MEMORY)
+ xmlXIncludeErrMemory(ctxt);
+ else
+ xmlXIncludeErr(ctxt, NULL, pctxt->errNo, "load error", NULL);
goto error;
+ }
buf = inputStream->buf;
if (buf == NULL)
goto error;
if (buf->encoder)
xmlCharEncCloseFunc(buf->encoder);
- buf->encoder = xmlGetCharEncodingHandler(enc);
+ buf->encoder = handler;
+ handler = NULL;
+
node = xmlNewDocText(ctxt->doc, NULL);
if (node == NULL) {
- xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
+ xmlXIncludeErrMemory(ctxt);
goto error;
}
/*
* Scan all chars from the resource and add the to the node
*/
- while (xmlParserInputBufferRead(buf, 4096) > 0)
- ;
+ do {
+ res = xmlParserInputBufferRead(buf, 4096);
+ } while (res > 0);
+ if (res < 0) {
+ if (buf->error == XML_ERR_NO_MEMORY)
+ xmlXIncludeErrMemory(ctxt);
+ else
+ xmlXIncludeErr(ctxt, NULL, buf->error, "read error", NULL);
+ goto error;
+ }
content = xmlBufContent(buf->buffer);
len = xmlBufLength(buf->buffer);
@@ -1719,14 +1690,15 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
cur = xmlGetUTF8Char(&content[i], &l);
if ((cur < 0) || (!IS_CHAR(cur))) {
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_INVALID_CHAR,
- "%s contains invalid char\n", URL);
+ "%s contains invalid char\n", url);
goto error;
}
i += l;
}
- xmlNodeAddContentLen(node, content, len);
+ if (xmlNodeAddContentLen(node, content, len) < 0)
+ xmlXIncludeErrMemory(ctxt);
if (ctxt->txtNr >= ctxt->txtMax) {
xmlXIncludeTxt *tmp;
@@ -1738,15 +1710,24 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
tmp = xmlRealloc(ctxt->txtTab, sizeof(xmlXIncludeTxt) * newSize);
if (tmp == NULL) {
- xmlXIncludeErrMemory(ctxt, ref->elem,
- "growing XInclude text table");
+ xmlXIncludeErrMemory(ctxt);
goto error;
}
ctxt->txtMax = newSize;
ctxt->txtTab = tmp;
}
ctxt->txtTab[ctxt->txtNr].text = xmlStrdup(node->content);
- ctxt->txtTab[ctxt->txtNr].url = xmlStrdup(URL);
+ if ((node->content != NULL) &&
+ (ctxt->txtTab[ctxt->txtNr].text == NULL)) {
+ xmlXIncludeErrMemory(ctxt);
+ goto error;
+ }
+ ctxt->txtTab[ctxt->txtNr].url = xmlStrdup(url);
+ if (ctxt->txtTab[ctxt->txtNr].url == NULL) {
+ xmlXIncludeErrMemory(ctxt);
+ xmlFree(ctxt->txtTab[ctxt->txtNr].text);
+ goto error;
+ }
ctxt->txtNr++;
loaded:
@@ -1761,9 +1742,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
xmlFreeNode(node);
xmlFreeInputStream(inputStream);
xmlFreeParserCtxt(pctxt);
+ xmlCharEncCloseFunc(handler);
xmlFree(encoding);
- xmlFreeURI(uri);
- xmlFree(URL);
return(ret);
}
@@ -1793,14 +1773,11 @@ xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback,
* (Bug 129969), so we re-process the fallback just in case
*/
oldNbErrors = ctxt->nbErrors;
- ref->inc = xmlXIncludeCopyNode(ctxt, fallback, 1);
+ ref->inc = xmlXIncludeCopyNode(ctxt, fallback, 1, ref->base);
if (ctxt->nbErrors > oldNbErrors)
ret = -1;
- else if (ref->inc == NULL)
- ref->emptyFb = 1;
} else {
ref->inc = NULL;
- ref->emptyFb = 1; /* flag empty callback */
}
ref->fallback = 1;
return(ret);
@@ -1896,12 +1873,6 @@ xmlXIncludeExpandNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
static int
xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
xmlNodePtr cur;
- xmlChar *href;
- xmlChar *parse;
- xmlChar *base;
- xmlChar *oldBase;
- xmlChar *URI;
- int xml = 1; /* default Issue 64 */
int ret;
if ((ctxt == NULL) || (ref == NULL))
@@ -1910,85 +1881,13 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
if (cur == NULL)
return(-1);
- /*
- * read the attributes
- */
- href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
- if (href == NULL) {
- href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
- if (href == NULL)
- return(-1);
- }
- parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
- if (parse != NULL) {
- if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
- xml = 1;
- else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
- xml = 0;
- else {
- xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_PARSE_VALUE,
- "invalid value %s for 'parse'\n", parse);
- if (href != NULL)
- xmlFree(href);
- if (parse != NULL)
- xmlFree(parse);
- return(-1);
- }
- }
-
- /*
- * compute the URI
- */
- base = xmlNodeGetBase(ctxt->doc, cur);
- if (base == NULL) {
- URI = xmlBuildURI(href, ctxt->doc->URL);
- } else {
- URI = xmlBuildURI(href, base);
- }
- if (URI == NULL) {
- xmlChar *escbase;
- xmlChar *eschref;
- /*
- * Some escaping may be needed
- */
- escbase = xmlURIEscape(base);
- eschref = xmlURIEscape(href);
- URI = xmlBuildURI(eschref, escbase);
- if (escbase != NULL)
- xmlFree(escbase);
- if (eschref != NULL)
- xmlFree(eschref);
- }
- if (URI == NULL) {
- xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
- "failed build URL\n", NULL);
- if (parse != NULL)
- xmlFree(parse);
- if (href != NULL)
- xmlFree(href);
- if (base != NULL)
- xmlFree(base);
- return(-1);
- }
-
- /*
- * Save the base for this include (saving the current one)
- */
- oldBase = ctxt->base;
- ctxt->base = base;
-
- if (xml) {
- ret = xmlXIncludeLoadDoc(ctxt, URI, ref);
+ if (ref->xml) {
+ ret = xmlXIncludeLoadDoc(ctxt, ref);
/* xmlXIncludeGetFragment(ctxt, cur, URI); */
} else {
- ret = xmlXIncludeLoadTxt(ctxt, URI, ref);
+ ret = xmlXIncludeLoadTxt(ctxt, ref);
}
- /*
- * Restore the original base before checking for fallback
- */
- ctxt->base = oldBase;
-
if (ret < 0) {
xmlNodePtr children;
@@ -2011,20 +1910,9 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
if (ret < 0) {
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_NO_FALLBACK,
"could not load %s, and no fallback was found\n",
- URI);
+ ref->URI);
}
- /*
- * Cleanup
- */
- if (URI != NULL)
- xmlFree(URI);
- if (parse != NULL)
- xmlFree(parse);
- if (href != NULL)
- xmlFree(href);
- if (base != NULL)
- xmlFree(base);
return(0);
}
@@ -2049,7 +1937,6 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
list = ref->inc;
ref->inc = NULL;
- ref->emptyFb = 0;
/*
* Check against the risk of generating a multi-rooted document
@@ -2076,16 +1963,19 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
if (ctxt->parseFlags & XML_PARSE_NOXINCNODE) {
/*
* Add the list of nodes
+ *
+ * TODO: Coalesce text nodes unless we are streaming mode.
*/
while (list != NULL) {
end = list;
list = list->next;
- xmlAddPrevSibling(cur, end);
+ if (xmlAddPrevSibling(cur, end) == NULL) {
+ xmlUnlinkNode(end);
+ xmlFreeNode(end);
+ goto err_memory;
+ }
}
- /*
- * FIXME: xmlUnlinkNode doesn't coalesce text nodes.
- */
xmlUnlinkNode(cur);
xmlFreeNode(cur);
} else {
@@ -2105,14 +1995,13 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
xmlFreeNode(child);
}
end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL);
- if (end == NULL) {
- xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_BUILD_FAILED,
- "failed to build node\n", NULL);
- xmlFreeNodeList(list);
- return(-1);
- }
+ if (end == NULL)
+ goto err_memory;
end->type = XML_XINCLUDE_END;
- xmlAddNextSibling(cur, end);
+ if (xmlAddNextSibling(cur, end) == NULL) {
+ xmlFreeNode(end);
+ goto err_memory;
+ }
/*
* Add the list of nodes
@@ -2121,12 +2010,21 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
cur = list;
list = list->next;
- xmlAddPrevSibling(end, cur);
+ if (xmlAddPrevSibling(end, cur) == NULL) {
+ xmlUnlinkNode(cur);
+ xmlFreeNode(cur);
+ goto err_memory;
+ }
}
}
return(0);
+
+err_memory:
+ xmlXIncludeErrMemory(ctxt);
+ xmlFreeNodeList(list);
+ return(-1);
}
/**
@@ -2222,11 +2120,6 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree) {
int ret = 0;
int i, start;
- if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL))
- return(-1);
- if (ctxt == NULL)
- return(-1);
-
/*
* First phase: lookup the elements in the document
*/
@@ -2263,10 +2156,7 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree) {
*/
for (i = start; i < ctxt->incNr; i++) {
if (ctxt->incTab[i]->replace != 0) {
- if ((ctxt->incTab[i]->inc != NULL) ||
- (ctxt->incTab[i]->emptyFb != 0)) { /* (empty fallback) */
- xmlXIncludeIncludeNode(ctxt, ctxt->incTab[i]);
- }
+ xmlXIncludeIncludeNode(ctxt, ctxt->incTab[i]);
ctxt->incTab[i]->replace = 0;
} else {
/*
@@ -2296,6 +2186,61 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree) {
return(ret);
}
+/**
+ * xmlXIncludeDoProcessRoot:
+ * @ctxt: the XInclude processing context
+ * @tree: the top of the tree to process
+ *
+ * Implement the XInclude substitution on the XML document @doc
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ * or the number of substitutions done.
+ */
+static int
+xmlXIncludeDoProcessRoot(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree) {
+ if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL))
+ return(-1);
+ if (ctxt == NULL)
+ return(-1);
+
+ return(xmlXIncludeDoProcess(ctxt, tree));
+}
+
+/**
+ * xmlXIncludeGetLastError:
+ * @ctxt: an XInclude processing context
+ *
+ * Available since 2.13.0.
+ *
+ * Returns the last error code.
+ */
+int
+xmlXIncludeGetLastError(xmlXIncludeCtxtPtr ctxt) {
+ if (ctxt == NULL)
+ return(XML_ERR_ARGUMENT);
+ return(ctxt->errNo);
+}
+
+/**
+ * xmlXIncludeSetErrorHandler:
+ * @ctxt: an XInclude processing context
+ * @handler: error handler
+ * @data: user data which will be passed to the handler
+ *
+ * Register a callback function that will be called on errors and
+ * warnings. If handler is NULL, the error handler will be deactivated.
+ *
+ * Available since 2.13.0.
+ */
+void
+xmlXIncludeSetErrorHandler(xmlXIncludeCtxtPtr ctxt,
+ xmlStructuredErrorFunc handler, void *data) {
+ if (ctxt == NULL)
+ return;
+ ctxt->errorHandler = handler;
+ ctxt->errorCtxt = data;
+}
+
/**
* xmlXIncludeSetFlags:
* @ctxt: an XInclude processing context
@@ -2356,9 +2301,8 @@ xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree, int flags, void *data) {
if (ctxt == NULL)
return(-1);
ctxt->_private = data;
- ctxt->base = xmlStrdup((xmlChar *)tree->doc->URL);
xmlXIncludeSetFlags(ctxt, flags);
- ret = xmlXIncludeDoProcess(ctxt, tree);
+ ret = xmlXIncludeDoProcessRoot(ctxt, tree);
if ((ret >= 0) && (ctxt->nbErrors > 0))
ret = -1;
@@ -2440,9 +2384,8 @@ xmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) {
ctxt = xmlXIncludeNewContext(tree->doc);
if (ctxt == NULL)
return(-1);
- ctxt->base = xmlNodeGetBase(tree->doc, tree);
xmlXIncludeSetFlags(ctxt, flags);
- ret = xmlXIncludeDoProcess(ctxt, tree);
+ ret = xmlXIncludeDoProcessRoot(ctxt, tree);
if ((ret >= 0) && (ctxt->nbErrors > 0))
ret = -1;
@@ -2482,7 +2425,7 @@ xmlXIncludeProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) ||
(node->doc == NULL) || (ctxt == NULL))
return(-1);
- ret = xmlXIncludeDoProcess(ctxt, node);
+ ret = xmlXIncludeDoProcessRoot(ctxt, node);
if ((ret >= 0) && (ctxt->nbErrors > 0))
ret = -1;
return(ret);
diff --git a/xmlIO.c b/xmlIO.c
index 22acb59..1156715 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -4,8 +4,6 @@
* See Copyright for the status of this software.
*
* daniel@veillard.com
- *
- * 14 Nov 2000 ht - for VMS, truncated name of long functions to under 32 char
*/
#define IN_LIBXML
@@ -44,22 +42,8 @@
#include
#endif
-#ifndef S_ISDIR
-# ifdef _S_ISDIR
-# define S_ISDIR(x) _S_ISDIR(x)
-# elif defined(S_IFDIR)
-# ifdef S_IFMT
-# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-# elif defined(_S_IFMT)
-# define S_ISDIR(m) (((m) & _S_IFMT) == S_IFDIR)
-# endif
-# endif
-#endif
-
#include
#include
-#include
-#include
#include
#include
#include
@@ -78,6 +62,22 @@
#define MINLEN 4000
+#ifndef STDOUT_FILENO
+ #define STDOUT_FILENO 1
+#endif
+
+#ifndef S_ISDIR
+# ifdef _S_ISDIR
+# define S_ISDIR(x) _S_ISDIR(x)
+# elif defined(S_IFDIR)
+# ifdef S_IFMT
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+# elif defined(_S_IFMT)
+# define S_ISDIR(m) (((m) & _S_IFMT) == S_IFDIR)
+# endif
+# endif
+#endif
+
/*
* Input I/O callback sets
*/
@@ -88,11 +88,14 @@ typedef struct _xmlInputCallback {
xmlInputCloseCallback closecallback;
} xmlInputCallback;
-#define MAX_INPUT_CALLBACK 15
+/* This dummy function only marks default IO in the callback table */
+static int
+xmlIODefaultMatch(const char *filename);
+
+#define MAX_INPUT_CALLBACK 10
static xmlInputCallback xmlInputCallbackTable[MAX_INPUT_CALLBACK];
-static int xmlInputCallbackNr = 0;
-static int xmlInputCallbackInitialized = 0;
+static int xmlInputCallbackNr;
#ifdef LIBXML_OUTPUT_ENABLED
/*
@@ -105,112 +108,18 @@ typedef struct _xmlOutputCallback {
xmlOutputCloseCallback closecallback;
} xmlOutputCallback;
-#define MAX_OUTPUT_CALLBACK 15
+#define MAX_OUTPUT_CALLBACK 10
static xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK];
-static int xmlOutputCallbackNr = 0;
-static int xmlOutputCallbackInitialized = 0;
+static int xmlOutputCallbackNr;
#endif /* LIBXML_OUTPUT_ENABLED */
/************************************************************************
* *
- * Tree memory error handler *
+ * Error handling *
* *
************************************************************************/
-static const char* const IOerr[] = {
- "Unknown IO error", /* UNKNOWN */
- "Permission denied", /* EACCES */
- "Resource temporarily unavailable",/* EAGAIN */
- "Bad file descriptor", /* EBADF */
- "Bad message", /* EBADMSG */
- "Resource busy", /* EBUSY */
- "Operation canceled", /* ECANCELED */
- "No child processes", /* ECHILD */
- "Resource deadlock avoided",/* EDEADLK */
- "Domain error", /* EDOM */
- "File exists", /* EEXIST */
- "Bad address", /* EFAULT */
- "File too large", /* EFBIG */
- "Operation in progress", /* EINPROGRESS */
- "Interrupted function call",/* EINTR */
- "Invalid argument", /* EINVAL */
- "Input/output error", /* EIO */
- "Is a directory", /* EISDIR */
- "Too many open files", /* EMFILE */
- "Too many links", /* EMLINK */
- "Inappropriate message buffer length",/* EMSGSIZE */
- "Filename too long", /* ENAMETOOLONG */
- "Too many open files in system",/* ENFILE */
- "No such device", /* ENODEV */
- "No such file or directory",/* ENOENT */
- "Exec format error", /* ENOEXEC */
- "No locks available", /* ENOLCK */
- "Not enough space", /* ENOMEM */
- "No space left on device", /* ENOSPC */
- "Function not implemented", /* ENOSYS */
- "Not a directory", /* ENOTDIR */
- "Directory not empty", /* ENOTEMPTY */
- "Not supported", /* ENOTSUP */
- "Inappropriate I/O control operation",/* ENOTTY */
- "No such device or address",/* ENXIO */
- "Operation not permitted", /* EPERM */
- "Broken pipe", /* EPIPE */
- "Result too large", /* ERANGE */
- "Read-only file system", /* EROFS */
- "Invalid seek", /* ESPIPE */
- "No such process", /* ESRCH */
- "Operation timed out", /* ETIMEDOUT */
- "Improper link", /* EXDEV */
- "Attempt to load network entity %s", /* XML_IO_NETWORK_ATTEMPT */
- "encoder error", /* XML_IO_ENCODER */
- "flush error",
- "write error",
- "no input",
- "buffer full",
- "loading error",
- "not a socket", /* ENOTSOCK */
- "already connected", /* EISCONN */
- "connection refused", /* ECONNREFUSED */
- "unreachable network", /* ENETUNREACH */
- "address in use", /* EADDRINUSE */
- "already in use", /* EALREADY */
- "unknown address family", /* EAFNOSUPPORT */
-};
-
-#if defined(_WIN32)
-/**
- * __xmlIOWin32UTF8ToWChar:
- * @u8String: uft-8 string
- *
- * Convert a string from utf-8 to wchar (WINDOWS ONLY!)
- */
-static wchar_t *
-__xmlIOWin32UTF8ToWChar(const char *u8String)
-{
- wchar_t *wString = NULL;
-
- if (u8String) {
- int wLen =
- MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, u8String,
- -1, NULL, 0);
- if (wLen) {
- wString = xmlMalloc(wLen * sizeof(wchar_t));
- if (wString) {
- if (MultiByteToWideChar
- (CP_UTF8, 0, u8String, -1, wString, wLen) == 0) {
- xmlFree(wString);
- wString = NULL;
- }
- }
- }
- }
-
- return wString;
-}
-#endif
-
-#if defined(LIBXML_HTTP_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
/**
* xmlIOErrMemory:
* @extra: extra information
@@ -218,11 +127,10 @@ __xmlIOWin32UTF8ToWChar(const char *u8String)
* Handle an out of memory condition
*/
static void
-xmlIOErrMemory(const char *extra)
+xmlIOErrMemory(void)
{
- __xmlSimpleError(XML_FROM_IO, XML_ERR_NO_MEMORY, NULL, NULL, extra);
+ xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_IO, NULL);
}
-#endif
/**
* __xmlIOErr:
@@ -232,13 +140,17 @@ xmlIOErrMemory(const char *extra)
*
* Handle an I/O error
*/
-void
+int
__xmlIOErr(int domain, int code, const char *extra)
{
- unsigned int idx;
+ xmlStructuredErrorFunc schannel = NULL;
+ xmlGenericErrorFunc channel = NULL;
+ void *data = NULL;
+ const char *fmt, *arg1, *arg2;
+ int res;
if (code == 0) {
- if (errno == 0) code = 0;
+ if (errno == 0) code = XML_IO_UNKNOWN;
#ifdef EACCES
else if (errno == EACCES) code = XML_IO_EACCES;
#endif
@@ -394,189 +306,49 @@ __xmlIOErr(int domain, int code, const char *extra)
#endif
else code = XML_IO_UNKNOWN;
}
- idx = 0;
- if (code >= XML_IO_UNKNOWN) idx = code - XML_IO_UNKNOWN;
- if (idx >= (sizeof(IOerr) / sizeof(IOerr[0]))) idx = 0;
-
- __xmlSimpleError(domain, code, NULL, IOerr[idx], extra);
-}
-
-/**
- * xmlIOErr:
- * @code: the error number
- * @extra: extra information
- *
- * Handle an I/O error
- */
-static void
-xmlIOErr(int code, const char *extra)
-{
- __xmlIOErr(XML_FROM_IO, code, extra);
-}
-/**
- * __xmlLoaderErr:
- * @ctx: the parser context
- * @extra: extra information
- *
- * Handle a resource access error
- */
-void
-__xmlLoaderErr(void *ctx, const char *msg, const char *filename)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlStructuredErrorFunc schannel = NULL;
- xmlGenericErrorFunc channel = NULL;
- void *data = NULL;
- xmlErrorLevel level = XML_ERR_ERROR;
-
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
- (ctxt->instate == XML_PARSER_EOF))
- return;
- if ((ctxt != NULL) && (ctxt->sax != NULL)) {
- if (ctxt->validate) {
- channel = ctxt->sax->error;
- level = XML_ERR_ERROR;
- } else {
- channel = ctxt->sax->warning;
- level = XML_ERR_WARNING;
- }
- if (ctxt->sax->initialized == XML_SAX2_MAGIC)
- schannel = ctxt->sax->serror;
- data = ctxt->userData;
+ if (xmlStructuredError) {
+ schannel = xmlStructuredError;
+ data = xmlStructuredErrorContext;
+ } else {
+ channel = xmlGenericError;
+ data = xmlGenericErrorContext;
}
- __xmlRaiseError(schannel, channel, data, ctxt, NULL, XML_FROM_IO,
- XML_IO_LOAD_ERROR, level, NULL, 0,
- filename, NULL, NULL, 0, 0,
- msg, filename);
-
-}
-/************************************************************************
- * *
- * Tree memory error handler *
- * *
- ************************************************************************/
-/**
- * xmlNormalizeWindowsPath:
- * @path: the input file path
- *
- * This function is obsolete. Please see xmlURIFromPath in uri.c for
- * a better solution.
- *
- * Returns a canonicalized version of the path
- */
-xmlChar *
-xmlNormalizeWindowsPath(const xmlChar *path)
-{
- return xmlCanonicPath(path);
-}
-
-/**
- * xmlCleanupInputCallbacks:
- *
- * clears the entire input callback table. this includes the
- * compiled-in I/O.
- */
-void
-xmlCleanupInputCallbacks(void)
-{
- int i;
-
- if (!xmlInputCallbackInitialized)
- return;
-
- for (i = xmlInputCallbackNr - 1; i >= 0; i--) {
- xmlInputCallbackTable[i].matchcallback = NULL;
- xmlInputCallbackTable[i].opencallback = NULL;
- xmlInputCallbackTable[i].readcallback = NULL;
- xmlInputCallbackTable[i].closecallback = NULL;
+ if (extra != NULL) {
+ fmt = "%s: %s";
+ } else {
+ fmt = "%s";
}
- xmlInputCallbackNr = 0;
- xmlInputCallbackInitialized = 0;
-}
-
-/**
- * xmlPopInputCallbacks:
- *
- * Clear the top input callback from the input stack. this includes the
- * compiled-in I/O.
- *
- * Returns the number of input callback registered or -1 in case of error.
- */
-int
-xmlPopInputCallbacks(void)
-{
- if (!xmlInputCallbackInitialized)
- return(-1);
-
- if (xmlInputCallbackNr <= 0)
- return(-1);
-
- xmlInputCallbackNr--;
- xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = NULL;
- xmlInputCallbackTable[xmlInputCallbackNr].opencallback = NULL;
- xmlInputCallbackTable[xmlInputCallbackNr].readcallback = NULL;
- xmlInputCallbackTable[xmlInputCallbackNr].closecallback = NULL;
-
- return(xmlInputCallbackNr);
-}
-
-#ifdef LIBXML_OUTPUT_ENABLED
-/**
- * xmlCleanupOutputCallbacks:
- *
- * clears the entire output callback table. this includes the
- * compiled-in I/O callbacks.
- */
-void
-xmlCleanupOutputCallbacks(void)
-{
- int i;
-
- if (!xmlOutputCallbackInitialized)
- return;
+ arg1 = xmlErrString(code);
+ arg2 = extra;
- for (i = xmlOutputCallbackNr - 1; i >= 0; i--) {
- xmlOutputCallbackTable[i].matchcallback = NULL;
- xmlOutputCallbackTable[i].opencallback = NULL;
- xmlOutputCallbackTable[i].writecallback = NULL;
- xmlOutputCallbackTable[i].closecallback = NULL;
+ res = __xmlRaiseError(schannel, channel, data, NULL, NULL,
+ domain, code, XML_ERR_ERROR, NULL, 0,
+ extra, NULL, NULL, 0, 0,
+ fmt, arg1, arg2);
+ if (res < 0) {
+ xmlIOErrMemory();
+ return(XML_ERR_NO_MEMORY);
}
- xmlOutputCallbackNr = 0;
- xmlOutputCallbackInitialized = 0;
+ return(code);
}
/**
- * xmlPopOutputCallbacks:
- *
- * Remove the top output callbacks from the output stack. This includes the
- * compiled-in I/O.
+ * xmlIOErr:
+ * @code: the error number
+ * @extra: extra information
*
- * Returns the number of output callback registered or -1 in case of error.
+ * Handle an I/O error
*/
-int
-xmlPopOutputCallbacks(void)
+static int
+xmlIOErr(int code, const char *extra)
{
- if (!xmlOutputCallbackInitialized)
- return(-1);
-
- if (xmlOutputCallbackNr <= 0)
- return(-1);
-
- xmlOutputCallbackNr--;
- xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = NULL;
- xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = NULL;
- xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = NULL;
- xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = NULL;
-
- return(xmlOutputCallbackNr);
+ return(__xmlIOErr(XML_FROM_IO, code, extra));
}
-#endif /* LIBXML_OUTPUT_ENABLED */
-
/************************************************************************
* *
* Standard I/O for file accesses *
@@ -594,100 +366,65 @@ typedef struct stat _stat_t;
#if defined(_WIN32)
/**
- * xmlWrapOpenUtf8:
- * @path: the path in utf-8 encoding
- * @mode: type of access (0 - read, 1 - write)
- *
- * function opens the file specified by @path
+ * __xmlIOWin32UTF8ToWChar:
+ * @u8String: uft-8 string
*
+ * Convert a string from utf-8 to wchar (WINDOWS ONLY!)
*/
-static FILE*
-xmlWrapOpenUtf8(const char *path,int mode)
-{
- FILE *fd = NULL;
- wchar_t *wPath;
-
- wPath = __xmlIOWin32UTF8ToWChar(path);
- if(wPath)
- {
- fd = _wfopen(wPath, mode ? L"wb" : L"rb");
- xmlFree(wPath);
- }
- /* maybe path in native encoding */
- if(fd == NULL)
- fd = fopen(path, mode ? "wb" : "rb");
-
- return fd;
-}
-
-#ifdef LIBXML_ZLIB_ENABLED
-static gzFile
-xmlWrapGzOpenUtf8(const char *path, const char *mode)
+static wchar_t *
+__xmlIOWin32UTF8ToWChar(const char *u8String)
{
- gzFile fd;
- wchar_t *wPath;
+ wchar_t *wString = NULL;
+ int i;
- fd = gzopen (path, mode);
- if (fd)
- return fd;
+ if (u8String) {
+ int wLen =
+ MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, u8String,
+ -1, NULL, 0);
+ if (wLen) {
+ wString = xmlMalloc(wLen * sizeof(wchar_t));
+ if (wString) {
+ if (MultiByteToWideChar
+ (CP_UTF8, 0, u8String, -1, wString, wLen) == 0) {
+ xmlFree(wString);
+ wString = NULL;
+ }
+ }
- wPath = __xmlIOWin32UTF8ToWChar(path);
- if(wPath)
- {
- int d, m = (strstr(mode, "r") ? O_RDONLY : O_RDWR);
-#ifdef _O_BINARY
- m |= (strstr(mode, "b") ? _O_BINARY : 0);
-#endif
- d = _wopen(wPath, m);
- if (d >= 0)
- fd = gzdopen(d, mode);
- xmlFree(wPath);
+ /*
+ * Convert to backward slash
+ */
+ for (i = 0; wString[i] != 0; i++) {
+ if (wString[i] == '/')
+ wString[i] = '\\';
+ }
+ }
}
- return fd;
+ return wString;
}
+
#endif
/**
- * xmlWrapStatUtf8:
- * @path: the path in utf-8 encoding
- * @info: structure that stores results
+ * xmlNormalizeWindowsPath:
+ * @path: the input file path
*
- * function obtains information about the file or directory
+ * DEPRECATED: This never really worked.
*
+ * Returns a copy of path.
*/
-static int
-xmlWrapStatUtf8(const char *path, _stat_t *info) {
- int retval = -1;
- wchar_t *wPath;
-
- wPath = __xmlIOWin32UTF8ToWChar(path);
- if (wPath) {
-#if defined(_MSC_VER) && _MSC_VER >= 1500
- retval = _wstat64(wPath, info);
-#else
- retval = _wstat(wPath, info);
-#endif
- xmlFree(wPath);
- }
- /* maybe path in native encoding */
- if(retval < 0)
-#if defined(_MSC_VER) && _MSC_VER >= 1500
- retval = _stat64(path, info);
-#else
- retval = _stat(path, info);
-#endif
- return retval;
+xmlChar *
+xmlNormalizeWindowsPath(const xmlChar *path)
+{
+ return xmlStrdup(path);
}
-#endif
-
/**
* xmlCheckFilename:
* @path: the path to check
*
- * function checks to see if @path is a valid source
- * (file, socket...) for XML.
+ * DEPRECATED: Internal function, don't use.
*
* if stat is not available on the target machine,
* returns 1. if stat fails, returns 0 (if calling
@@ -695,40 +432,162 @@ xmlWrapStatUtf8(const char *path, _stat_t *info) {
* if stat succeeds and the file is a directory,
* returns 2. otherwise returns 1.
*/
-
int
-xmlCheckFilename (const char *path)
+xmlCheckFilename(const char *path)
{
#ifdef HAVE_STAT
- _stat_t stat_buffer;
+#if defined(_MSC_VER) && _MSC_VER >= 1500
+ struct _stat64 stat_buffer;
+#else
+ struct stat stat_buffer;
#endif
+ int res;
+#endif
+
if (path == NULL)
return(0);
#ifdef HAVE_STAT
#if defined(_WIN32)
- /*
- * On Windows stat and wstat do not work with long pathname,
- * which start with '\\?\'
- */
- if ((path[0] == '\\') && (path[1] == '\\') && (path[2] == '?') &&
- (path[3] == '\\') )
- return 1;
+ {
+ wchar_t *wpath;
- if (xmlWrapStatUtf8(path, &stat_buffer) == -1)
- return 0;
+ /*
+ * On Windows stat and wstat do not work with long pathname,
+ * which start with '\\?\'
+ */
+ if ((path[0] == '\\') && (path[1] == '\\') && (path[2] == '?') &&
+ (path[3] == '\\') )
+ return 1;
+
+ wpath = __xmlIOWin32UTF8ToWChar(path);
+ if (wpath == NULL)
+ return(0);
+#if defined(_MSC_VER) && _MSC_VER >= 1500
+ res = _wstat64(wpath, &stat_buffer);
#else
- if (stat(path, &stat_buffer) == -1)
- return 0;
-#endif
-#ifdef S_ISDIR
- if (S_ISDIR(stat_buffer.st_mode))
- return 2;
+ res = _wstat(wpath, &stat_buffer);
+#endif
+ xmlFree(wpath);
+ }
+#else
+ res = stat(path, &stat_buffer);
+#endif
+
+ if (res < 0)
+ return 0;
+
+#ifdef S_ISDIR
+ if (S_ISDIR(stat_buffer.st_mode))
+ return 2;
#endif
#endif /* HAVE_STAT */
+
return 1;
}
+static int
+xmlConvertUriToPath(const char *uri, char **out) {
+ const char *escaped;
+ char *unescaped;
+
+ *out = NULL;
+
+ if (!xmlStrncasecmp(BAD_CAST uri, BAD_CAST "file://localhost/", 17)) {
+ escaped = &uri[16];
+ } else if (!xmlStrncasecmp(BAD_CAST uri, BAD_CAST "file:///", 8)) {
+ escaped = &uri[7];
+ } else if (!xmlStrncasecmp(BAD_CAST uri, BAD_CAST "file:/", 6)) {
+ /* lots of generators seems to lazy to read RFC 1738 */
+ escaped = &uri[5];
+ } else {
+ return(1);
+ }
+
+#ifdef _WIN32
+ /* Ignore slash like in file:///C:/file.txt */
+ escaped += 1;
+#endif
+
+ unescaped = xmlURIUnescapeString(escaped, 0, NULL);
+ if (unescaped == NULL)
+ return(-1);
+
+ *out = unescaped;
+ return(0);
+}
+
+/**
+ * xmlFdOpen:
+ * @filename: the URI for matching
+ * @out: pointer to resulting context
+ *
+ * Returns an xmlParserErrors code
+ */
+static int
+xmlFdOpen(const char *filename, int write, int *out) {
+ char *fromUri = NULL;
+ int flags;
+ int fd;
+ int ret;
+
+ *out = -1;
+ if (filename == NULL)
+ return(XML_ERR_ARGUMENT);
+
+ if (xmlConvertUriToPath(filename, &fromUri) < 0)
+ return(XML_ERR_NO_MEMORY);
+
+ if (fromUri != NULL)
+ filename = fromUri;
+
+#if defined(_WIN32)
+ {
+ wchar_t *wpath;
+
+ wpath = __xmlIOWin32UTF8ToWChar(filename);
+ if (wpath == NULL) {
+ xmlFree(fromUri);
+ return(XML_ERR_NO_MEMORY);
+ }
+ if (write)
+ flags = _O_WRONLY | _O_CREAT | _O_TRUNC;
+ else
+ flags = _O_RDONLY;
+ fd = _wopen(wpath, flags | _O_BINARY, 0777);
+ xmlFree(wpath);
+ }
+#else
+ if (write)
+ flags = O_WRONLY | O_CREAT | O_TRUNC;
+ else
+ flags = O_RDONLY;
+ fd = open(filename, flags, 0777);
+#endif /* WIN32 */
+
+ if (fd < 0) {
+ /*
+ * Windows and possibly other platforms return EINVAL
+ * for invalid filenames.
+ */
+ if ((errno == ENOENT) || (errno == EINVAL)) {
+ ret = XML_IO_ENOENT;
+ } else {
+ /*
+ * This error won't be forwarded to the parser context
+ * which will report it a second time.
+ */
+ ret = xmlIOErr(0, filename);
+ }
+ } else {
+ *out = fd;
+ ret = XML_ERR_OK;
+ }
+
+ xmlFree(fromUri);
+ return(ret);
+}
+
/**
* xmlFdRead:
* @context: the I/O context
@@ -737,14 +596,32 @@ xmlCheckFilename (const char *path)
*
* Read @len bytes to @buffer from the I/O channel.
*
- * Returns the number of bytes written
+ * Returns the number of bytes read
*/
static int
-xmlFdRead (void * context, char * buffer, int len) {
- int ret;
+xmlFdRead(void *context, char *buffer, int len) {
+ int fd = (int) (ptrdiff_t) context;
+ int ret = 0;
+ int bytes;
+
+ while (len > 0) {
+ bytes = read(fd, buffer, len);
+ if (bytes < 0) {
+ /*
+ * If we already got some bytes, return them without
+ * raising an error.
+ */
+ if (ret > 0)
+ break;
+ return(-xmlIOErr(0, "read()"));
+ }
+ if (bytes == 0)
+ break;
+ ret += bytes;
+ buffer += bytes;
+ len -= bytes;
+ }
- ret = read((int) (ptrdiff_t) context, &buffer[0], len);
- if (ret < 0) xmlIOErr(0, "read()");
return(ret);
}
@@ -760,13 +637,20 @@ xmlFdRead (void * context, char * buffer, int len) {
* Returns the number of bytes written
*/
static int
-xmlFdWrite (void * context, const char * buffer, int len) {
+xmlFdWrite(void *context, const char *buffer, int len) {
+ int fd = (int) (ptrdiff_t) context;
int ret = 0;
+ int bytes;
- if (len > 0) {
- ret = write((int) (ptrdiff_t) context, &buffer[0], len);
- if (ret < 0) xmlIOErr(0, "write()");
+ while (len > 0) {
+ bytes = write(fd, buffer, len);
+ if (bytes < 0)
+ return(-xmlIOErr(0, "write()"));
+ ret += bytes;
+ buffer += bytes;
+ len -= bytes;
}
+
return(ret);
}
#endif /* LIBXML_OUTPUT_ENABLED */
@@ -782,16 +666,19 @@ xmlFdWrite (void * context, const char * buffer, int len) {
static int
xmlFdClose (void * context) {
int ret;
+
ret = close((int) (ptrdiff_t) context);
- if (ret < 0) xmlIOErr(0, "close()");
- return(ret);
+ if (ret < 0)
+ return(xmlIOErr(0, "close()"));
+
+ return(XML_ERR_OK);
}
/**
* xmlFileMatch:
* @filename: the URI for matching
*
- * input from FILE *
+ * DEPRECATED: Internal function, don't use.
*
* Returns 1 if matches, 0 otherwise
*/
@@ -801,139 +688,82 @@ xmlFileMatch (const char *filename ATTRIBUTE_UNUSED) {
}
/**
- * xmlFileOpen_real:
+ * xmlFileOpenSafe:
* @filename: the URI for matching
+ * @out: pointer to resulting context
*
- * input from FILE *, supports compressed input
- * if @filename is " " then the standard input is used
+ * input from FILE *
*
* Returns an I/O context or NULL in case of error
*/
-static void *
-xmlFileOpen_real (const char *filename) {
- const char *path = filename;
+static int
+xmlFileOpenSafe(const char *filename, int write, void **out) {
+ char *fromUri = NULL;
FILE *fd;
+ int ret = XML_ERR_OK;
+ *out = NULL;
if (filename == NULL)
- return(NULL);
-
- if (!strcmp(filename, "-")) {
- fd = stdin;
- return((void *) fd);
- }
+ return(XML_ERR_ARGUMENT);
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) {
-#if defined (_WIN32)
- path = &filename[17];
-#else
- path = &filename[16];
-#endif
- } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32)
- path = &filename[8];
-#else
- path = &filename[7];
-#endif
- } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:/", 6)) {
- /* lots of generators seems to lazy to read RFC 1738 */
-#if defined (_WIN32)
- path = &filename[6];
-#else
- path = &filename[5];
-#endif
- }
+ if (xmlConvertUriToPath(filename, &fromUri) < 0)
+ return(XML_ERR_NO_MEMORY);
- /* Do not check DDNAME on zOS ! */
-#if !defined(__MVS__)
- if (!xmlCheckFilename(path))
- return(NULL);
-#endif
+ if (fromUri != NULL)
+ filename = fromUri;
#if defined(_WIN32)
- fd = xmlWrapOpenUtf8(path, 0);
+ {
+ wchar_t *wpath;
+
+ wpath = __xmlIOWin32UTF8ToWChar(filename);
+ if (wpath == NULL) {
+ xmlFree(fromUri);
+ return(XML_ERR_NO_MEMORY);
+ }
+ fd = _wfopen(wpath, write ? L"wb" : L"rb");
+ xmlFree(wpath);
+ }
#else
- fd = fopen(path, "rb");
+ fd = fopen(filename, write ? "wb" : "rb");
#endif /* WIN32 */
- if (fd == NULL) xmlIOErr(0, path);
- return((void *) fd);
-}
-/**
- * xmlFileOpen:
- * @filename: the URI for matching
- *
- * Wrapper around xmlFileOpen_real that try it with an unescaped
- * version of @filename, if this fails fallback to @filename
- *
- * Returns a handler or NULL in case or failure
- */
-void *
-xmlFileOpen (const char *filename) {
- char *unescaped;
- void *retval;
-
- retval = xmlFileOpen_real(filename);
- if (retval == NULL) {
- unescaped = xmlURIUnescapeString(filename, 0, NULL);
- if (unescaped != NULL) {
- retval = xmlFileOpen_real(unescaped);
- xmlFree(unescaped);
- }
+ if (fd == NULL) {
+ /*
+ * Windows and possibly other platforms return EINVAL
+ * for invalid filenames.
+ */
+ if ((errno == ENOENT) || (errno == EINVAL)) {
+ ret = XML_IO_ENOENT;
+ } else {
+ /*
+ * This error won't be forwarded to the parser context
+ * which will report it a second time.
+ */
+ ret = xmlIOErr(0, filename);
+ }
}
- return retval;
+ *out = fd;
+ xmlFree(fromUri);
+ return(ret);
}
-#ifdef LIBXML_OUTPUT_ENABLED
/**
- * xmlFileOpenW:
+ * xmlFileOpen:
* @filename: the URI for matching
*
- * output to from FILE *,
- * if @filename is "-" then the standard output is used
+ * DEPRECATED: Internal function, don't use.
*
- * Returns an I/O context or NULL in case of error
+ * Returns an IO context or NULL in case or failure
*/
-static void *
-xmlFileOpenW (const char *filename) {
- const char *path = NULL;
- FILE *fd;
-
- if (!strcmp(filename, "-")) {
- fd = stdout;
- return((void *) fd);
- }
-
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32)
- path = &filename[17];
-#else
- path = &filename[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32)
- path = &filename[8];
-#else
- path = &filename[7];
-#endif
- } else
- path = filename;
-
- if (path == NULL)
- return(NULL);
-
-#if defined(_WIN32)
- fd = xmlWrapOpenUtf8(path, 1);
-#elif(__MVS__)
- fd = fopen(path, "w");
-#else
- fd = fopen(path, "wb");
-#endif /* WIN32 */
+void *
+xmlFileOpen(const char *filename) {
+ void *context;
- if (fd == NULL) xmlIOErr(0, path);
- return((void *) fd);
+ xmlFileOpenSafe(filename, 0, &context);
+ return(context);
}
-#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlFileRead:
@@ -941,18 +771,30 @@ xmlFileOpenW (const char *filename) {
* @buffer: where to drop data
* @len: number of bytes to write
*
- * Read @len bytes to @buffer from the I/O channel.
+ * DEPRECATED: Internal function, don't use.
*
- * Returns the number of bytes written or < 0 in case of failure
+ * Returns the number of bytes read or < 0 in case of failure
*/
int
-xmlFileRead (void * context, char * buffer, int len) {
- int ret;
+xmlFileRead(void * context, char * buffer, int len) {
+ FILE *file = context;
+ size_t bytes;
+
if ((context == NULL) || (buffer == NULL))
return(-1);
- ret = fread(&buffer[0], 1, len, (FILE *) context);
- if (ret < 0) xmlIOErr(0, "fread()");
- return(ret);
+
+ /*
+ * The C standard doesn't mandate that fread sets errno, only
+ * POSIX does. The Windows documentation isn't really clear.
+ * Set errno to zero which will be reported as unknown error
+ * if fread fails without setting errno.
+ */
+ errno = 0;
+ bytes = fread(buffer, 1, len, file);
+ if ((bytes < (size_t) len) && (ferror(file)))
+ return(-xmlIOErr(0, "fread()"));
+
+ return(len);
}
#ifdef LIBXML_OUTPUT_ENABLED
@@ -967,66 +809,65 @@ xmlFileRead (void * context, char * buffer, int len) {
* Returns the number of bytes written
*/
static int
-xmlFileWrite (void * context, const char * buffer, int len) {
- int items;
+xmlFileWrite(void *context, const char *buffer, int len) {
+ FILE *file = context;
+ size_t bytes;
if ((context == NULL) || (buffer == NULL))
return(-1);
- items = fwrite(&buffer[0], len, 1, (FILE *) context);
- if ((items == 0) && (ferror((FILE *) context))) {
- xmlIOErr(0, "fwrite()");
- return(-1);
- }
- return(items * len);
+
+ errno = 0;
+ bytes = fwrite(buffer, 1, len, file);
+ if (bytes < (size_t) len)
+ return(-xmlIOErr(0, "fwrite()"));
+
+ return(len);
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**
- * xmlFileClose:
+ * xmlFileFlush:
* @context: the I/O context
*
- * Close an I/O channel
- *
- * Returns 0 or -1 in case of error
+ * Flush an I/O channel
*/
-int
-xmlFileClose (void * context) {
- FILE *fil;
- int ret;
+static int
+xmlFileFlush (void * context) {
+ FILE *file = context;
- if (context == NULL)
+ if (file == NULL)
return(-1);
- fil = (FILE *) context;
- if ((fil == stdout) || (fil == stderr)) {
- ret = fflush(fil);
- if (ret < 0)
- xmlIOErr(0, "fflush()");
- return(0);
- }
- if (fil == stdin)
- return(0);
- ret = ( fclose((FILE *) context) == EOF ) ? -1 : 0;
- if (ret < 0)
- xmlIOErr(0, "fclose()");
- return(ret);
+
+ if (fflush(file) != 0)
+ return(xmlIOErr(0, "fflush()"));
+
+ return(XML_ERR_OK);
}
/**
- * xmlFileFlush:
+ * xmlFileClose:
* @context: the I/O context
*
- * Flush an I/O channel
+ * DEPRECATED: Internal function, don't use.
+ *
+ * Returns 0 or -1 an error code case of error
*/
-static int
-xmlFileFlush (void * context) {
- int ret;
+int
+xmlFileClose (void * context) {
+ FILE *file = context;
if (context == NULL)
return(-1);
- ret = ( fflush((FILE *) context) == EOF ) ? -1 : 0;
- if (ret < 0)
- xmlIOErr(0, "fflush()");
- return(ret);
+
+ if (file == stdin)
+ return(0);
+ if ((file == stdout) || (file == stderr))
+ return(xmlFileFlush(file));
+
+ if (fclose(file) != 0)
+ return(xmlIOErr(0, "fclose()"));
+
+ return(0);
}
#ifdef LIBXML_OUTPUT_ENABLED
@@ -1038,7 +879,8 @@ xmlFileFlush (void * context) {
*
* Write @len bytes from @buffer to the xml buffer
*
- * Returns the number of bytes written
+ * Returns the number of bytes written or a negative xmlParserErrors
+ * value.
*/
static int
xmlBufferWrite (void * context, const char * buffer, int len) {
@@ -1046,7 +888,7 @@ xmlBufferWrite (void * context, const char * buffer, int len) {
ret = xmlBufferAdd((xmlBufferPtr) context, (const xmlChar *) buffer, len);
if (ret != 0)
- return(-1);
+ return(-XML_ERR_NO_MEMORY);
return(len);
}
#endif
@@ -1057,148 +899,6 @@ xmlBufferWrite (void * context, const char * buffer, int len) {
* I/O for compressed file accesses *
* *
************************************************************************/
-/**
- * xmlGzfileMatch:
- * @filename: the URI for matching
- *
- * input from compressed file test
- *
- * Returns 1 if matches, 0 otherwise
- */
-static int
-xmlGzfileMatch (const char *filename ATTRIBUTE_UNUSED) {
- return(1);
-}
-
-/**
- * xmlGzfileOpen_real:
- * @filename: the URI for matching
- *
- * input from compressed file open
- * if @filename is " " then the standard input is used
- *
- * Returns an I/O context or NULL in case of error
- */
-static void *
-xmlGzfileOpen_real (const char *filename) {
- const char *path = NULL;
- gzFile fd;
-
- if (!strcmp(filename, "-")) {
- int duped_fd = dup(fileno(stdin));
- fd = gzdopen(duped_fd, "rb");
- if (fd == Z_NULL && duped_fd >= 0) {
- close(duped_fd); /* gzdOpen() does not close on failure */
- }
-
- return((void *) fd);
- }
-
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32)
- path = &filename[17];
-#else
- path = &filename[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32)
- path = &filename[8];
-#else
- path = &filename[7];
-#endif
- } else
- path = filename;
-
- if (path == NULL)
- return(NULL);
- if (!xmlCheckFilename(path))
- return(NULL);
-
-#if defined(_WIN32)
- fd = xmlWrapGzOpenUtf8(path, "rb");
-#else
- fd = gzopen(path, "rb");
-#endif
- return((void *) fd);
-}
-
-/**
- * xmlGzfileOpen:
- * @filename: the URI for matching
- *
- * Wrapper around xmlGzfileOpen_real if the open fails, it will
- * try to unescape @filename
- */
-static void *
-xmlGzfileOpen (const char *filename) {
- char *unescaped;
- void *retval;
-
- retval = xmlGzfileOpen_real(filename);
- if (retval == NULL) {
- unescaped = xmlURIUnescapeString(filename, 0, NULL);
- if (unescaped != NULL) {
- retval = xmlGzfileOpen_real(unescaped);
- }
- xmlFree(unescaped);
- }
- return retval;
-}
-
-#ifdef LIBXML_OUTPUT_ENABLED
-/**
- * xmlGzfileOpenW:
- * @filename: the URI for matching
- * @compression: the compression factor (0 - 9 included)
- *
- * input from compressed file open
- * if @filename is " " then the standard input is used
- *
- * Returns an I/O context or NULL in case of error
- */
-static void *
-xmlGzfileOpenW (const char *filename, int compression) {
- const char *path = NULL;
- char mode[15];
- gzFile fd;
-
- snprintf(mode, sizeof(mode), "wb%d", compression);
- if (!strcmp(filename, "-")) {
- int duped_fd = dup(fileno(stdout));
- fd = gzdopen(duped_fd, "rb");
- if (fd == Z_NULL && duped_fd >= 0) {
- close(duped_fd); /* gzdOpen() does not close on failure */
- }
-
- return((void *) fd);
- }
-
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32)
- path = &filename[17];
-#else
- path = &filename[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32)
- path = &filename[8];
-#else
- path = &filename[7];
-#endif
- } else
- path = filename;
-
- if (path == NULL)
- return(NULL);
-
-#if defined(_WIN32)
- fd = xmlWrapGzOpenUtf8(path, mode);
-#else
- fd = gzopen(path, mode);
-#endif
- return((void *) fd);
-}
-#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlGzfileRead:
@@ -1256,95 +956,21 @@ xmlGzfileClose (void * context) {
}
#endif /* LIBXML_ZLIB_ENABLED */
-#ifdef LIBXML_LZMA_ENABLED
/************************************************************************
* *
* I/O for compressed file accesses *
* *
************************************************************************/
+
+#ifdef LIBXML_LZMA_ENABLED
+
#include "private/xzlib.h"
+
/**
- * xmlXzfileMatch:
- * @filename: the URI for matching
- *
- * input from compressed file test
- *
- * Returns 1 if matches, 0 otherwise
- */
-static int
-xmlXzfileMatch (const char *filename ATTRIBUTE_UNUSED) {
- return(1);
-}
-
-/**
- * xmlXzFileOpen_real:
- * @filename: the URI for matching
- *
- * input from compressed file open
- * if @filename is " " then the standard input is used
- *
- * Returns an I/O context or NULL in case of error
- */
-static void *
-xmlXzfileOpen_real (const char *filename) {
- const char *path = NULL;
- xzFile fd;
-
- if (!strcmp(filename, "-")) {
- fd = __libxml2_xzdopen(dup(fileno(stdin)), "rb");
- return((void *) fd);
- }
-
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) {
- path = &filename[16];
- } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
- path = &filename[7];
- } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:/", 6)) {
- /* lots of generators seems to lazy to read RFC 1738 */
- path = &filename[5];
- } else
- path = filename;
-
- if (path == NULL)
- return(NULL);
- if (!xmlCheckFilename(path))
- return(NULL);
-
- fd = __libxml2_xzopen(path, "rb");
- return((void *) fd);
-}
-
-/**
- * xmlXzfileOpen:
- * @filename: the URI for matching
- *
- * Wrapper around xmlXzfileOpen_real that try it with an unescaped
- * version of @filename, if this fails fallback to @filename
- *
- * Returns a handler or NULL in case or failure
- */
-static void *
-xmlXzfileOpen (const char *filename) {
- char *unescaped;
- void *retval;
-
- retval = xmlXzfileOpen_real(filename);
- if (retval == NULL) {
- unescaped = xmlURIUnescapeString(filename, 0, NULL);
- if (unescaped != NULL) {
- retval = xmlXzfileOpen_real(unescaped);
- }
- xmlFree(unescaped);
- }
-
- return retval;
-}
-
-/**
- * xmlXzfileRead:
- * @context: the I/O context
- * @buffer: where to drop data
- * @len: number of bytes to write
+ * xmlXzfileRead:
+ * @context: the I/O context
+ * @buffer: where to drop data
+ * @len: number of bytes to write
*
* Read @len bytes to @buffer from the compressed I/O channel.
*
@@ -1375,371 +1001,19 @@ xmlXzfileClose (void * context) {
}
#endif /* LIBXML_LZMA_ENABLED */
-#ifdef LIBXML_HTTP_ENABLED
/************************************************************************
* *
* I/O for HTTP file accesses *
* *
************************************************************************/
-#ifdef LIBXML_OUTPUT_ENABLED
-typedef struct xmlIOHTTPWriteCtxt_
-{
- int compression;
-
- char * uri;
-
- void * doc_buff;
-
-} xmlIOHTTPWriteCtxt, *xmlIOHTTPWriteCtxtPtr;
-
-#ifdef LIBXML_ZLIB_ENABLED
-
-#define DFLT_WBITS ( -15 )
-#define DFLT_MEM_LVL ( 8 )
-#define GZ_MAGIC1 ( 0x1f )
-#define GZ_MAGIC2 ( 0x8b )
-#define LXML_ZLIB_OS_CODE ( 0x03 )
-#define INIT_HTTP_BUFF_SIZE ( 32768 )
-#define DFLT_ZLIB_RATIO ( 5 )
-
-/*
-** Data structure and functions to work with sending compressed data
-** via HTTP.
-*/
-
-typedef struct xmlZMemBuff_
-{
- unsigned long size;
- unsigned long crc;
-
- unsigned char * zbuff;
- z_stream zctrl;
-
-} xmlZMemBuff, *xmlZMemBuffPtr;
-
-/**
- * append_reverse_ulong
- * @buff: Compressed memory buffer
- * @data: Unsigned long to append
- *
- * Append a unsigned long in reverse byte order to the end of the
- * memory buffer.
- */
-static void
-append_reverse_ulong( xmlZMemBuff * buff, unsigned long data ) {
-
- int idx;
-
- if ( buff == NULL )
- return;
-
- /*
- ** This is plagiarized from putLong in gzio.c (zlib source) where
- ** the number "4" is hardcoded. If zlib is ever patched to
- ** support 64 bit file sizes, this code would need to be patched
- ** as well.
- */
-
- for ( idx = 0; idx < 4; idx++ ) {
- *buff->zctrl.next_out = ( data & 0xff );
- data >>= 8;
- buff->zctrl.next_out++;
- }
-
- return;
-}
-
-/**
- *
- * xmlFreeZMemBuff
- * @buff: The memory buffer context to clear
- *
- * Release all the resources associated with the compressed memory buffer.
- */
-static void
-xmlFreeZMemBuff( xmlZMemBuffPtr buff ) {
-
- if ( buff == NULL )
- return;
-
- xmlFree( buff->zbuff );
- deflateEnd( &buff->zctrl );
-
- xmlFree( buff );
- return;
-}
-
-/**
- * xmlCreateZMemBuff
- *@compression: Compression value to use
- *
- * Create a memory buffer to hold the compressed XML document. The
- * compressed document in memory will end up being identical to what
- * would be created if gzopen/gzwrite/gzclose were being used to
- * write the document to disk. The code for the header/trailer data to
- * the compression is plagiarized from the zlib source files.
- */
-static void *
-xmlCreateZMemBuff( int compression ) {
-
- int z_err;
- int hdr_lgth;
- xmlZMemBuffPtr buff = NULL;
-
- if ( ( compression < 1 ) || ( compression > 9 ) )
- return ( NULL );
-
- /* Create the control and data areas */
-
- buff = xmlMalloc( sizeof( xmlZMemBuff ) );
- if ( buff == NULL ) {
- xmlIOErrMemory("creating buffer context");
- return ( NULL );
- }
-
- (void)memset( buff, 0, sizeof( xmlZMemBuff ) );
- buff->size = INIT_HTTP_BUFF_SIZE;
- buff->zbuff = xmlMalloc( buff->size );
- if ( buff->zbuff == NULL ) {
- xmlFreeZMemBuff( buff );
- xmlIOErrMemory("creating buffer");
- return ( NULL );
- }
-
- z_err = deflateInit2( &buff->zctrl, compression, Z_DEFLATED,
- DFLT_WBITS, DFLT_MEM_LVL, Z_DEFAULT_STRATEGY );
- if ( z_err != Z_OK ) {
- xmlChar msg[500];
- xmlFreeZMemBuff( buff );
- buff = NULL;
- xmlStrPrintf(msg, 500,
- "xmlCreateZMemBuff: %s %d\n",
- "Error initializing compression context. ZLIB error:",
- z_err );
- xmlIOErr(XML_IO_WRITE, (const char *) msg);
- return ( NULL );
- }
-
- /* Set the header data. The CRC will be needed for the trailer */
- buff->crc = crc32( 0L, NULL, 0 );
- hdr_lgth = snprintf( (char *)buff->zbuff, buff->size,
- "%c%c%c%c%c%c%c%c%c%c",
- GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED,
- 0, 0, 0, 0, 0, 0, LXML_ZLIB_OS_CODE );
- buff->zctrl.next_out = buff->zbuff + hdr_lgth;
- buff->zctrl.avail_out = buff->size - hdr_lgth;
-
- return ( buff );
-}
-
-/**
- * xmlZMemBuffExtend
- * @buff: Buffer used to compress and consolidate data.
- * @ext_amt: Number of bytes to extend the buffer.
- *
- * Extend the internal buffer used to store the compressed data by the
- * specified amount.
- *
- * Returns 0 on success or -1 on failure to extend the buffer. On failure
- * the original buffer still exists at the original size.
- */
-static int
-xmlZMemBuffExtend( xmlZMemBuffPtr buff, size_t ext_amt ) {
-
- int rc = -1;
- size_t new_size;
- size_t cur_used;
-
- unsigned char * tmp_ptr = NULL;
-
- if ( buff == NULL )
- return ( -1 );
-
- else if ( ext_amt == 0 )
- return ( 0 );
-
- cur_used = buff->zctrl.next_out - buff->zbuff;
- new_size = buff->size + ext_amt;
-
- tmp_ptr = xmlRealloc( buff->zbuff, new_size );
- if ( tmp_ptr != NULL ) {
- rc = 0;
- buff->size = new_size;
- buff->zbuff = tmp_ptr;
- buff->zctrl.next_out = tmp_ptr + cur_used;
- buff->zctrl.avail_out = new_size - cur_used;
- }
- else {
- xmlChar msg[500];
- xmlStrPrintf(msg, 500,
- "xmlZMemBuffExtend: %s %lu bytes.\n",
- "Allocation failure extending output buffer to",
- (unsigned long) new_size );
- xmlIOErr(XML_IO_WRITE, (const char *) msg);
- }
-
- return ( rc );
-}
-
-/**
- * xmlZMemBuffAppend
- * @buff: Buffer used to compress and consolidate data
- * @src: Uncompressed source content to append to buffer
- * @len: Length of source data to append to buffer
- *
- * Compress and append data to the internal buffer. The data buffer
- * will be expanded if needed to store the additional data.
- *
- * Returns the number of bytes appended to the buffer or -1 on error.
- */
-static int
-xmlZMemBuffAppend( xmlZMemBuffPtr buff, const char * src, int len ) {
-
- int z_err;
- size_t min_accept;
-
- if ( ( buff == NULL ) || ( src == NULL ) )
- return ( -1 );
-
- buff->zctrl.avail_in = len;
- buff->zctrl.next_in = (unsigned char *)src;
- while ( buff->zctrl.avail_in > 0 ) {
- /*
- ** Extend the buffer prior to deflate call if a reasonable amount
- ** of output buffer space is not available.
- */
- min_accept = buff->zctrl.avail_in / DFLT_ZLIB_RATIO;
- if ( buff->zctrl.avail_out <= min_accept ) {
- if ( xmlZMemBuffExtend( buff, buff->size ) == -1 )
- return ( -1 );
- }
-
- z_err = deflate( &buff->zctrl, Z_NO_FLUSH );
- if ( z_err != Z_OK ) {
- xmlChar msg[500];
- xmlStrPrintf(msg, 500,
- "xmlZMemBuffAppend: %s %d %s - %d",
- "Compression error while appending",
- len, "bytes to buffer. ZLIB error", z_err );
- xmlIOErr(XML_IO_WRITE, (const char *) msg);
- return ( -1 );
- }
- }
-
- buff->crc = crc32( buff->crc, (unsigned char *)src, len );
-
- return ( len );
-}
-
-/**
- * xmlZMemBuffGetContent
- * @buff: Compressed memory content buffer
- * @data_ref: Pointer reference to point to compressed content
- *
- * Flushes the compression buffers, appends gzip file trailers and
- * returns the compressed content and length of the compressed data.
- * NOTE: The gzip trailer code here is plagiarized from zlib source.
- *
- * Returns the length of the compressed data or -1 on error.
- */
-static int
-xmlZMemBuffGetContent( xmlZMemBuffPtr buff, char ** data_ref ) {
-
- int zlgth = -1;
- int z_err;
-
- if ( ( buff == NULL ) || ( data_ref == NULL ) )
- return ( -1 );
-
- /* Need to loop until compression output buffers are flushed */
-
- do
- {
- z_err = deflate( &buff->zctrl, Z_FINISH );
- if ( z_err == Z_OK ) {
- /* In this case Z_OK means more buffer space needed */
-
- if ( xmlZMemBuffExtend( buff, buff->size ) == -1 )
- return ( -1 );
- }
- }
- while ( z_err == Z_OK );
-
- /* If the compression state is not Z_STREAM_END, some error occurred */
-
- if ( z_err == Z_STREAM_END ) {
-
- /* Need to append the gzip data trailer */
-
- if ( buff->zctrl.avail_out < ( 2 * sizeof( unsigned long ) ) ) {
- if ( xmlZMemBuffExtend(buff, (2 * sizeof(unsigned long))) == -1 )
- return ( -1 );
- }
-
- /*
- ** For whatever reason, the CRC and length data are pushed out
- ** in reverse byte order. So a memcpy can't be used here.
- */
-
- append_reverse_ulong( buff, buff->crc );
- append_reverse_ulong( buff, buff->zctrl.total_in );
-
- zlgth = buff->zctrl.next_out - buff->zbuff;
- *data_ref = (char *)buff->zbuff;
- }
-
- else {
- xmlChar msg[500];
- xmlStrPrintf(msg, 500,
- "xmlZMemBuffGetContent: %s - %d\n",
- "Error flushing zlib buffers. Error code", z_err );
- xmlIOErr(XML_IO_WRITE, (const char *) msg);
- }
-
- return ( zlgth );
-}
-#endif /* LIBXML_OUTPUT_ENABLED */
-#endif /* LIBXML_ZLIB_ENABLED */
-
-#ifdef LIBXML_OUTPUT_ENABLED
-/**
- * xmlFreeHTTPWriteCtxt
- * @ctxt: Context to cleanup
- *
- * Free allocated memory and reclaim system resources.
- *
- * No return value.
- */
-static void
-xmlFreeHTTPWriteCtxt( xmlIOHTTPWriteCtxtPtr ctxt )
-{
- if ( ctxt->uri != NULL )
- xmlFree( ctxt->uri );
-
- if ( ctxt->doc_buff != NULL ) {
-
-#ifdef LIBXML_ZLIB_ENABLED
- if ( ctxt->compression > 0 ) {
- xmlFreeZMemBuff( ctxt->doc_buff );
- }
- else
-#endif
- {
- xmlOutputBufferClose( ctxt->doc_buff );
- }
- }
-
- xmlFree( ctxt );
- return;
-}
-#endif /* LIBXML_OUTPUT_ENABLED */
-
-
+#ifdef LIBXML_HTTP_ENABLED
/**
* xmlIOHTTPMatch:
* @filename: the URI for matching
*
+ * DEPRECATED: Internal function, don't use.
+ *
* check if the URI matches an HTTP one
*
* Returns 1 if matches, 0 otherwise
@@ -1755,6 +1029,8 @@ xmlIOHTTPMatch (const char *filename) {
* xmlIOHTTPOpen:
* @filename: the URI for matching
*
+ * DEPRECATED: Internal function, don't use.
+ *
* open an HTTP I/O channel
*
* Returns an I/O context or NULL in case of error
@@ -1770,78 +1046,15 @@ xmlIOHTTPOpen (const char *filename) {
* @post_uri: The destination URI for the document
* @compression: The compression desired for the document.
*
- * Open a temporary buffer to collect the document for a subsequent HTTP POST
- * request. Non-static as is called from the output buffer creation routine.
+ * DEPRECATED: Support for HTTP POST has been removed.
*
- * Returns an I/O context or NULL in case of error.
+ * Returns NULL.
*/
-
void *
-xmlIOHTTPOpenW(const char *post_uri, int compression ATTRIBUTE_UNUSED)
+xmlIOHTTPOpenW(const char *post_uri ATTRIBUTE_UNUSED,
+ int compression ATTRIBUTE_UNUSED)
{
-
- xmlIOHTTPWriteCtxtPtr ctxt = NULL;
-
- if (post_uri == NULL)
- return (NULL);
-
- ctxt = xmlMalloc(sizeof(xmlIOHTTPWriteCtxt));
- if (ctxt == NULL) {
- xmlIOErrMemory("creating HTTP output context");
- return (NULL);
- }
-
- (void) memset(ctxt, 0, sizeof(xmlIOHTTPWriteCtxt));
-
- ctxt->uri = (char *) xmlStrdup((const xmlChar *)post_uri);
- if (ctxt->uri == NULL) {
- xmlIOErrMemory("copying URI");
- xmlFreeHTTPWriteCtxt(ctxt);
- return (NULL);
- }
-
- /*
- * ** Since the document length is required for an HTTP post,
- * ** need to put the document into a buffer. A memory buffer
- * ** is being used to avoid pushing the data to disk and back.
- */
-
-#ifdef LIBXML_ZLIB_ENABLED
- if ((compression > 0) && (compression <= 9)) {
-
- ctxt->compression = compression;
- ctxt->doc_buff = xmlCreateZMemBuff(compression);
- } else
-#endif
- {
- /* Any character conversions should have been done before this */
-
- ctxt->doc_buff = xmlAllocOutputBufferInternal(NULL);
- }
-
- if (ctxt->doc_buff == NULL) {
- xmlFreeHTTPWriteCtxt(ctxt);
- ctxt = NULL;
- }
-
- return (ctxt);
-}
-#endif /* LIBXML_OUTPUT_ENABLED */
-
-#ifdef LIBXML_OUTPUT_ENABLED
-/**
- * xmlIOHTTPDfltOpenW
- * @post_uri: The destination URI for this document.
- *
- * Calls xmlIOHTTPOpenW with no compression to set up for a subsequent
- * HTTP post command. This function should generally not be used as
- * the open callback is short circuited in xmlOutputBufferCreateFile.
- *
- * Returns a pointer to the new IO context.
- */
-static void *
-xmlIOHTTPDfltOpenW( const char * post_uri ) {
- return ( xmlIOHTTPOpenW( post_uri, 0 ) );
+ return(NULL);
}
#endif /* LIBXML_OUTPUT_ENABLED */
@@ -1851,6 +1064,8 @@ xmlIOHTTPDfltOpenW( const char * post_uri ) {
* @buffer: where to drop data
* @len: number of bytes to write
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Read @len bytes to @buffer from the I/O channel.
*
* Returns the number of bytes written
@@ -1861,59 +1076,12 @@ xmlIOHTTPRead(void * context, char * buffer, int len) {
return(xmlNanoHTTPRead(context, &buffer[0], len));
}
-#ifdef LIBXML_OUTPUT_ENABLED
-/**
- * xmlIOHTTPWrite
- * @context: previously opened writing context
- * @buffer: data to output to temporary buffer
- * @len: bytes to output
- *
- * Collect data from memory buffer into a temporary file for later
- * processing.
- *
- * Returns number of bytes written.
- */
-
-static int
-xmlIOHTTPWrite( void * context, const char * buffer, int len ) {
-
- xmlIOHTTPWriteCtxtPtr ctxt = context;
-
- if ( ( ctxt == NULL ) || ( ctxt->doc_buff == NULL ) || ( buffer == NULL ) )
- return ( -1 );
-
- if ( len > 0 ) {
-
- /* Use gzwrite or fwrite as previously setup in the open call */
-
-#ifdef LIBXML_ZLIB_ENABLED
- if ( ctxt->compression > 0 )
- len = xmlZMemBuffAppend( ctxt->doc_buff, buffer, len );
-
- else
-#endif
- len = xmlOutputBufferWrite( ctxt->doc_buff, len, buffer );
-
- if ( len < 0 ) {
- xmlChar msg[500];
- xmlStrPrintf(msg, 500,
- "xmlIOHTTPWrite: %s\n%s '%s'.\n",
- "Error appending to internal buffer.",
- "Error sending document to URI",
- ctxt->uri );
- xmlIOErr(XML_IO_WRITE, (const char *) msg);
- }
- }
-
- return ( len );
-}
-#endif /* LIBXML_OUTPUT_ENABLED */
-
-
/**
* xmlIOHTTPClose:
* @context: the I/O context
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Close an HTTP I/O channel
*
* Returns 0
@@ -1923,119 +1091,6 @@ xmlIOHTTPClose (void * context) {
xmlNanoHTTPClose(context);
return 0;
}
-
-#ifdef LIBXML_OUTPUT_ENABLED
-/**
- * xmlIOHTTCloseWrite
- * @context: The I/O context
- * @http_mthd: The HTTP method to be used when sending the data
- *
- * Close the transmit HTTP I/O channel and actually send the data.
- */
-static int
-xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) {
-
- int close_rc = -1;
- int http_rtn = 0;
- int content_lgth = 0;
- xmlIOHTTPWriteCtxtPtr ctxt = context;
-
- char * http_content = NULL;
- char * content_encoding = NULL;
- char * content_type = (char *) "text/xml";
- void * http_ctxt = NULL;
-
- if ( ( ctxt == NULL ) || ( http_mthd == NULL ) )
- return ( -1 );
-
- /* Retrieve the content from the appropriate buffer */
-
-#ifdef LIBXML_ZLIB_ENABLED
-
- if ( ctxt->compression > 0 ) {
- content_lgth = xmlZMemBuffGetContent( ctxt->doc_buff, &http_content );
- content_encoding = (char *) "Content-Encoding: gzip";
- }
- else
-#endif
- {
- /* Pull the data out of the memory output buffer */
-
- xmlOutputBufferPtr dctxt = ctxt->doc_buff;
- http_content = (char *) xmlBufContent(dctxt->buffer);
- content_lgth = xmlBufUse(dctxt->buffer);
- }
-
- if ( http_content == NULL ) {
- xmlChar msg[500];
- xmlStrPrintf(msg, 500,
- "xmlIOHTTPCloseWrite: %s '%s' %s '%s'.\n",
- "Error retrieving content.\nUnable to",
- http_mthd, "data to URI", ctxt->uri );
- xmlIOErr(XML_IO_WRITE, (const char *) msg);
- }
-
- else {
-
- http_ctxt = xmlNanoHTTPMethod( ctxt->uri, http_mthd, http_content,
- &content_type, content_encoding,
- content_lgth );
-
- if ( http_ctxt != NULL ) {
-
- http_rtn = xmlNanoHTTPReturnCode( http_ctxt );
- if ( ( http_rtn >= 200 ) && ( http_rtn < 300 ) )
- close_rc = 0;
- else {
- xmlChar msg[500];
- xmlStrPrintf(msg, 500,
- "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n",
- http_mthd, content_lgth,
- "bytes to URI", ctxt->uri,
- "failed. HTTP return code:", http_rtn );
- xmlIOErr(XML_IO_WRITE, (const char *) msg);
- }
-
- xmlNanoHTTPClose( http_ctxt );
- xmlFree( content_type );
- }
- }
-
- /* Final cleanups */
-
- xmlFreeHTTPWriteCtxt( ctxt );
-
- return ( close_rc );
-}
-
-/**
- * xmlIOHTTPClosePut
- *
- * @context: The I/O context
- *
- * Close the transmit HTTP I/O channel and actually send data using a PUT
- * HTTP method.
- */
-static int
-xmlIOHTTPClosePut( void * ctxt ) {
- return ( xmlIOHTTPCloseWrite( ctxt, "PUT" ) );
-}
-
-
-/**
- * xmlIOHTTPClosePost
- *
- * @context: The I/O context
- *
- * Close the transmit HTTP I/O channel and actually send data using a POST
- * HTTP method.
- */
-static int
-xmlIOHTTPClosePost( void * ctxt ) {
- return ( xmlIOHTTPCloseWrite( ctxt, "POST" ) );
-}
-#endif /* LIBXML_OUTPUT_ENABLED */
-
#endif /* LIBXML_HTTP_ENABLED */
#ifdef LIBXML_FTP_ENABLED
@@ -2048,6 +1103,8 @@ xmlIOHTTPClosePost( void * ctxt ) {
* xmlIOFTPMatch:
* @filename: the URI for matching
*
+ * DEPRECATED: Internal function, don't use.
+ *
* check if the URI matches an FTP one
*
* Returns 1 if matches, 0 otherwise
@@ -2063,6 +1120,8 @@ xmlIOFTPMatch (const char *filename) {
* xmlIOFTPOpen:
* @filename: the URI for matching
*
+ * DEPRECATED: Internal function, don't use.
+ *
* open an FTP I/O channel
*
* Returns an I/O context or NULL in case of error
@@ -2078,6 +1137,8 @@ xmlIOFTPOpen (const char *filename) {
* @buffer: where to drop data
* @len: number of bytes to write
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Read @len bytes to @buffer from the I/O channel.
*
* Returns the number of bytes written
@@ -2092,6 +1153,8 @@ xmlIOFTPRead(void * context, char * buffer, int len) {
* xmlIOFTPClose:
* @context: the I/O context
*
+ * DEPRECATED: Internal function, don't use.
+ *
* Close an FTP I/O channel
*
* Returns 0
@@ -2102,161 +1165,192 @@ xmlIOFTPClose (void * context) {
}
#endif /* LIBXML_FTP_ENABLED */
+/************************************************************************
+ * *
+ * Input/output buffers *
+ * *
+ ************************************************************************/
-/**
- * xmlRegisterInputCallbacks:
- * @matchFunc: the xmlInputMatchCallback
- * @openFunc: the xmlInputOpenCallback
- * @readFunc: the xmlInputReadCallback
- * @closeFunc: the xmlInputCloseCallback
- *
- * Register a new set of I/O callback for handling parser input.
- *
- * Returns the registered handler number or -1 in case of error
- */
-int
-xmlRegisterInputCallbacks(xmlInputMatchCallback matchFunc,
- xmlInputOpenCallback openFunc, xmlInputReadCallback readFunc,
- xmlInputCloseCallback closeFunc) {
- if (xmlInputCallbackNr >= MAX_INPUT_CALLBACK) {
- return(-1);
- }
- xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = matchFunc;
- xmlInputCallbackTable[xmlInputCallbackNr].opencallback = openFunc;
- xmlInputCallbackTable[xmlInputCallbackNr].readcallback = readFunc;
- xmlInputCallbackTable[xmlInputCallbackNr].closecallback = closeFunc;
- xmlInputCallbackInitialized = 1;
- return(xmlInputCallbackNr++);
+static int
+xmlIODefaultMatch(const char *filename ATTRIBUTE_UNUSED) {
+ return(1);
}
-#ifdef LIBXML_OUTPUT_ENABLED
/**
- * xmlRegisterOutputCallbacks:
- * @matchFunc: the xmlOutputMatchCallback
- * @openFunc: the xmlOutputOpenCallback
- * @writeFunc: the xmlOutputWriteCallback
- * @closeFunc: the xmlOutputCloseCallback
+ * xmlInputDefaultOpen:
+ * @buf: input buffer to be filled
+ * @filename: filename or URI
*
- * Register a new set of I/O callback for handling output.
- *
- * Returns the registered handler number or -1 in case of error
+ * Returns an xmlParserErrors code.
*/
-int
-xmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc,
- xmlOutputOpenCallback openFunc, xmlOutputWriteCallback writeFunc,
- xmlOutputCloseCallback closeFunc) {
- if (xmlOutputCallbackNr >= MAX_OUTPUT_CALLBACK) {
- return(-1);
+static int
+xmlInputDefaultOpen(xmlParserInputBufferPtr buf, const char *filename) {
+ int ret;
+ int fd;
+
+#ifdef LIBXML_FTP_ENABLED
+ if (xmlIOFTPMatch(filename)) {
+ buf->context = xmlIOFTPOpen(filename);
+
+ if (buf->context != NULL) {
+ buf->readcallback = xmlIOFTPRead;
+ buf->closecallback = xmlIOFTPClose;
+ return(XML_ERR_OK);
+ }
}
- xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = matchFunc;
- xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = openFunc;
- xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = writeFunc;
- xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = closeFunc;
- xmlOutputCallbackInitialized = 1;
- return(xmlOutputCallbackNr++);
-}
-#endif /* LIBXML_OUTPUT_ENABLED */
+#endif /* LIBXML_FTP_ENABLED */
-/**
- * xmlRegisterDefaultInputCallbacks:
- *
- * Registers the default compiled-in I/O handlers.
- */
-void
-xmlRegisterDefaultInputCallbacks(void) {
- if (xmlInputCallbackInitialized)
- return;
+#ifdef LIBXML_HTTP_ENABLED
+ if (xmlIOHTTPMatch(filename)) {
+ buf->context = xmlIOHTTPOpen(filename);
+
+ if (buf->context != NULL) {
+ buf->readcallback = xmlIOHTTPRead;
+ buf->closecallback = xmlIOHTTPClose;
+ return(XML_ERR_OK);
+ }
+ }
+#endif /* LIBXML_HTTP_ENABLED */
+
+ if (!xmlFileMatch(filename))
+ return(XML_IO_ENOENT);
- xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen,
- xmlFileRead, xmlFileClose);
-#ifdef LIBXML_ZLIB_ENABLED
- xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
- xmlGzfileRead, xmlGzfileClose);
-#endif /* LIBXML_ZLIB_ENABLED */
#ifdef LIBXML_LZMA_ENABLED
- xmlRegisterInputCallbacks(xmlXzfileMatch, xmlXzfileOpen,
- xmlXzfileRead, xmlXzfileClose);
+ {
+ xzFile xzStream;
+
+ ret = xmlFdOpen(filename, 0, &fd);
+ if (ret != XML_ERR_OK)
+ return(ret);
+
+ xzStream = __libxml2_xzdopen(filename, fd, "rb");
+
+ if (xzStream == NULL) {
+ close(fd);
+ } else {
+ if (__libxml2_xzcompressed(xzStream) > 0) {
+ buf->context = xzStream;
+ buf->readcallback = xmlXzfileRead;
+ buf->closecallback = xmlXzfileClose;
+ buf->compressed = 1;
+
+ return(XML_ERR_OK);
+ }
+
+ xmlXzfileClose(xzStream);
+ }
+ }
#endif /* LIBXML_LZMA_ENABLED */
-#ifdef LIBXML_HTTP_ENABLED
- xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
- xmlIOHTTPRead, xmlIOHTTPClose);
-#endif /* LIBXML_HTTP_ENABLED */
+#ifdef LIBXML_ZLIB_ENABLED
+ {
+ gzFile gzStream;
-#ifdef LIBXML_FTP_ENABLED
- xmlRegisterInputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
- xmlIOFTPRead, xmlIOFTPClose);
-#endif /* LIBXML_FTP_ENABLED */
- xmlInputCallbackInitialized = 1;
+ ret = xmlFdOpen(filename, 0, &fd);
+ if (ret != XML_ERR_OK)
+ return(ret);
+
+ gzStream = gzdopen(fd, "rb");
+
+ if (gzStream == NULL) {
+ close(fd);
+ } else {
+ char buff4[4];
+
+ if ((gzread(gzStream, buff4, 4) > 0) &&
+ (gzdirect(gzStream) == 0)) {
+ gzrewind(gzStream);
+
+ buf->context = gzStream;
+ buf->readcallback = xmlGzfileRead;
+ buf->closecallback = xmlGzfileClose;
+ buf->compressed = 1;
+
+ return(XML_ERR_OK);
+ }
+
+ xmlGzfileClose(gzStream);
+ }
+ }
+#endif /* LIBXML_ZLIB_ENABLED */
+
+ ret = xmlFdOpen(filename, 0, &fd);
+ if (ret != XML_ERR_OK)
+ return(ret);
+
+ buf->context = (void *) (ptrdiff_t) fd;
+ buf->readcallback = xmlFdRead;
+ buf->closecallback = xmlFdClose;
+ return(XML_ERR_OK);
}
#ifdef LIBXML_OUTPUT_ENABLED
/**
- * xmlRegisterDefaultOutputCallbacks:
+ * xmlOutputDefaultOpen:
+ * @buf: input buffer to be filled
+ * @filename: filename or URI
+ * @compression: compression level or 0
+ * @is_file_uri: whether filename is a file URI
*
- * Registers the default compiled-in I/O handlers.
+ * Returns an xmlParserErrors code.
*/
-void
-xmlRegisterDefaultOutputCallbacks (void) {
- if (xmlOutputCallbackInitialized)
- return;
+static int
+xmlOutputDefaultOpen(xmlOutputBufferPtr buf, const char *filename,
+ int compression) {
+ int fd;
- xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW,
- xmlFileWrite, xmlFileClose);
+ (void) compression;
-#ifdef LIBXML_HTTP_ENABLED
- xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPDfltOpenW,
- xmlIOHTTPWrite, xmlIOHTTPClosePut);
-#endif
+ if (!strcmp(filename, "-")) {
+ fd = dup(STDOUT_FILENO);
+
+ if (fd < 0)
+ return(xmlIOErr(0, "dup()"));
+ } else {
+ int ret;
-/*********************************
- No way a-priori to distinguish between gzipped files from
- uncompressed ones except opening if existing then closing
- and saving with same compression ratio ... a pain.
+ ret = xmlFdOpen(filename, /* write */ 1, &fd);
+ if (ret != XML_ERR_OK)
+ return(ret);
+ }
#ifdef LIBXML_ZLIB_ENABLED
- xmlRegisterOutputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
- xmlGzfileWrite, xmlGzfileClose);
-#endif
+ if ((compression > 0) && (compression <= 9)) {
+ gzFile gzStream;
+ char mode[15];
- Nor FTP PUT ....
-#ifdef LIBXML_FTP_ENABLED
- xmlRegisterOutputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
- xmlIOFTPWrite, xmlIOFTPClose);
-#endif
- **********************************/
- xmlOutputCallbackInitialized = 1;
-}
+ snprintf(mode, sizeof(mode), "wb%d", compression);
+ gzStream = gzdopen(fd, mode);
-#ifdef LIBXML_HTTP_ENABLED
-/**
- * xmlRegisterHTTPPostCallbacks:
- *
- * By default, libxml submits HTTP output requests using the "PUT" method.
- * Calling this method changes the HTTP output method to use the "POST"
- * method instead.
- *
- */
-void
-xmlRegisterHTTPPostCallbacks( void ) {
+ if (gzStream == NULL) {
+ close(fd);
+ return(xmlIOErr(XML_IO_UNKNOWN, "gzdopen()"));
+ }
- /* Register defaults if not done previously */
+ buf->context = gzStream;
+ buf->writecallback = xmlGzfileWrite;
+ buf->closecallback = xmlGzfileClose;
- if ( xmlOutputCallbackInitialized == 0 )
- xmlRegisterDefaultOutputCallbacks( );
+ return(XML_ERR_OK);
+ }
+#endif /* LIBXML_ZLIB_ENABLED */
- xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPDfltOpenW,
- xmlIOHTTPWrite, xmlIOHTTPClosePost);
- return;
+ buf->context = (void *) (ptrdiff_t) fd;
+ buf->writecallback = xmlFdWrite;
+ buf->closecallback = xmlFdClose;
+ return(XML_ERR_OK);
}
#endif
-#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlAllocParserInputBuffer:
- * @enc: the charset encoding if known
+ * @enc: the charset encoding if known (deprecated)
+ *
+ * Create a buffered parser input for progressive parsing.
*
- * Create a buffered parser input for progressive parsing
+ * The encoding argument is deprecated and should be set to
+ * XML_CHAR_ENCODING_NONE. The encoding can be changed with
+ * xmlSwitchEncoding or xmlSwitchEncodingName later on.
*
* Returns the new parser input or NULL
*/
@@ -2275,7 +1369,13 @@ xmlAllocParserInputBuffer(xmlCharEncoding enc) {
return(NULL);
}
xmlBufSetAllocationScheme(ret->buffer, XML_BUFFER_ALLOC_DOUBLEIT);
- ret->encoder = xmlGetCharEncodingHandler(enc);
+ if (enc != XML_CHAR_ENCODING_NONE) {
+ if (xmlLookupCharEncodingHandler(enc, &ret->encoder) != 0) {
+ /* We can't handle errors properly here. */
+ xmlFreeParserInputBuffer(ret);
+ return(NULL);
+ }
+ }
if (ret->encoder != NULL)
ret->raw = xmlBufCreateSize(2 * xmlDefaultBufferSize);
else
@@ -2312,7 +1412,7 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
xmlFree(ret);
return(NULL);
}
- xmlBufSetAllocationScheme(ret->buffer, XML_BUFFER_ALLOC_DOUBLEIT);
+ xmlBufSetAllocationScheme(ret->buffer, XML_BUFFER_ALLOC_IO);
ret->encoder = encoder;
if (encoder != NULL) {
@@ -2427,22 +1527,36 @@ xmlFreeParserInputBuffer(xmlParserInputBufferPtr in) {
* flushes and close the output I/O channel
* and free up all the associated resources
*
- * Returns the number of byte written or -1 in case of error.
+ * Returns the number of byte written or a negative xmlParserErrors
+ * code in case of error.
*/
int
xmlOutputBufferClose(xmlOutputBufferPtr out)
{
- int written;
- int err_rc = 0;
+ int ret;
if (out == NULL)
return (-1);
+
if (out->writecallback != NULL)
xmlOutputBufferFlush(out);
+
if (out->closecallback != NULL) {
- err_rc = out->closecallback(out->context);
+ int code = out->closecallback(out->context);
+
+ if ((code != XML_ERR_OK) && (out->error == XML_ERR_OK)) {
+ if (code < 0)
+ out->error = XML_IO_UNKNOWN;
+ else
+ out->error = code;
+ }
}
- written = out->written;
+
+ if (out->error != XML_ERR_OK)
+ ret = -out->error;
+ else
+ ret = out->written;
+
if (out->conv) {
xmlBufFree(out->conv);
out->conv = NULL;
@@ -2455,81 +1569,77 @@ xmlOutputBufferClose(xmlOutputBufferPtr out)
out->buffer = NULL;
}
- if (out->error)
- err_rc = -1;
xmlFree(out);
- return ((err_rc == 0) ? written : err_rc);
+
+ return(ret);
}
#endif /* LIBXML_OUTPUT_ENABLED */
-xmlParserInputBufferPtr
-__xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
- xmlParserInputBufferPtr ret;
- int i = 0;
- void *context = NULL;
+/**
+ * xmlParserInputBufferCreateFilenameInt:
+ * @URI: the filename or URI
+ * @enc: encoding enum (deprecated)
+ * @out: pointer to resulting input buffer
+ *
+ * Returns an xmlParserErrors code.
+ */
+static int
+xmlParserInputBufferCreateFilenameInt(const char *URI, xmlCharEncoding enc,
+ xmlParserInputBufferPtr *out) {
+ xmlParserInputBufferPtr buf;
+ int ret;
+ int i;
- if (xmlInputCallbackInitialized == 0)
- xmlRegisterDefaultInputCallbacks();
+ *out = NULL;
+ if (URI == NULL)
+ return(XML_ERR_ARGUMENT);
- if (URI == NULL) return(NULL);
+ /*
+ * Allocate the Input buffer front-end.
+ */
+ buf = xmlAllocParserInputBuffer(enc);
+ if (buf == NULL)
+ return(XML_ERR_NO_MEMORY);
/*
* Try to find one of the input accept method accepting that scheme
* Go in reverse to give precedence to user defined handlers.
*/
- if (context == NULL) {
- for (i = xmlInputCallbackNr - 1;i >= 0;i--) {
- if ((xmlInputCallbackTable[i].matchcallback != NULL) &&
- (xmlInputCallbackTable[i].matchcallback(URI) != 0)) {
- context = xmlInputCallbackTable[i].opencallback(URI);
- if (context != NULL) {
- break;
- }
- }
- }
+ ret = XML_IO_ENOENT;
+ for (i = xmlInputCallbackNr - 1; i >= 0; i--) {
+ xmlInputCallback *cb = &xmlInputCallbackTable[i];
+
+ if (cb->matchcallback == xmlIODefaultMatch) {
+ ret = xmlInputDefaultOpen(buf, URI);
+
+ if ((ret == XML_ERR_OK) || (ret != XML_IO_ENOENT))
+ break;
+ } else if ((cb->matchcallback != NULL) &&
+ (cb->matchcallback(URI) != 0)) {
+ buf->context = cb->opencallback(URI);
+ if (buf->context != NULL) {
+ buf->readcallback = cb->readcallback;
+ buf->closecallback = cb->closecallback;
+ ret = XML_ERR_OK;
+ break;
+ }
+ }
}
- if (context == NULL) {
- return(NULL);
+ if (ret != XML_ERR_OK) {
+ xmlFreeParserInputBuffer(buf);
+ *out = NULL;
+ return(ret);
}
- /*
- * Allocate the Input buffer front-end.
- */
- ret = xmlAllocParserInputBuffer(enc);
- if (ret != NULL) {
- ret->context = context;
- ret->readcallback = xmlInputCallbackTable[i].readcallback;
- ret->closecallback = xmlInputCallbackTable[i].closecallback;
-#ifdef LIBXML_ZLIB_ENABLED
- if ((xmlInputCallbackTable[i].opencallback == xmlGzfileOpen) &&
- (strcmp(URI, "-") != 0)) {
-#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230
- ret->compressed = !gzdirect(context);
-#else
- if (((z_stream *)context)->avail_in > 4) {
- char *cptr, buff4[4];
- cptr = (char *) ((z_stream *)context)->next_in;
- if (gzread(context, buff4, 4) == 4) {
- if (strncmp(buff4, cptr, 4) == 0)
- ret->compressed = 0;
- else
- ret->compressed = 1;
- gzrewind(context);
- }
- }
-#endif
- }
-#endif
-#ifdef LIBXML_LZMA_ENABLED
- if ((xmlInputCallbackTable[i].opencallback == xmlXzfileOpen) &&
- (strcmp(URI, "-") != 0)) {
- ret->compressed = __libxml2_xzcompressed(context);
- }
-#endif
- }
- else
- xmlInputCallbackTable[i].closecallback (context);
+ *out = buf;
+ return(ret);
+}
+
+xmlParserInputBufferPtr
+__xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
+ xmlParserInputBufferPtr ret;
+ xmlParserInputBufferCreateFilenameInt(URI, enc, &ret);
return(ret);
}
@@ -2539,7 +1649,6 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
* @enc: the charset encoding if known
*
* Create a buffered parser input for the progressive parsing of a file
- * If filename is "-' then we use stdin as the input.
* Automatic support for ZLIB/Compress compressed document is provided
* by default if found at compile-time.
* Do an encoding check if enc == XML_CHAR_ENCODING_NONE
@@ -2548,135 +1657,104 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
- if ((xmlParserInputBufferCreateFilenameValue)) {
- return xmlParserInputBufferCreateFilenameValue(URI, enc);
- }
- return __xmlParserInputBufferCreateFilename(URI, enc);
+ if (xmlParserInputBufferCreateFilenameValue != NULL)
+ return(xmlParserInputBufferCreateFilenameValue(URI, enc));
+
+ return(__xmlParserInputBufferCreateFilename(URI, enc));
+}
+
+/**
+ * xmlParserInputBufferCreateFilenameSafe:
+ * @URI: the filename or URI
+ * @enc: encoding enum (deprecated)
+ * @out: pointer to resulting input buffer
+ *
+ * Create an input buffer for a filename or URI.
+ *
+ * Returns an xmlParserErrors code.
+ */
+int
+xmlParserInputBufferCreateFilenameSafe(const char *URI, xmlCharEncoding enc,
+ xmlParserInputBufferPtr *out) {
+ if (xmlParserInputBufferCreateFilenameValue != NULL) {
+ *out = xmlParserInputBufferCreateFilenameValue(URI, enc);
+
+ if (*out == NULL)
+ return(XML_IO_ENOENT);
+ return(XML_ERR_OK);
+ }
+
+ return(xmlParserInputBufferCreateFilenameInt(URI, enc, out));
}
#ifdef LIBXML_OUTPUT_ENABLED
xmlOutputBufferPtr
__xmlOutputBufferCreateFilename(const char *URI,
xmlCharEncodingHandlerPtr encoder,
- int compression ATTRIBUTE_UNUSED) {
+ int compression) {
xmlOutputBufferPtr ret;
xmlURIPtr puri;
int i = 0;
- void *context = NULL;
char *unescaped = NULL;
-#ifdef LIBXML_ZLIB_ENABLED
- int is_file_uri = 1;
-#endif
-
- if (xmlOutputCallbackInitialized == 0)
- xmlRegisterDefaultOutputCallbacks();
- if (URI == NULL) return(NULL);
+ if (URI == NULL)
+ return(NULL);
puri = xmlParseURI(URI);
if (puri != NULL) {
-#ifdef LIBXML_ZLIB_ENABLED
- if ((puri->scheme != NULL) &&
- (!xmlStrEqual(BAD_CAST puri->scheme, BAD_CAST "file")))
- is_file_uri = 0;
-#endif
- /*
- * try to limit the damages of the URI unescaping code.
- */
- if ((puri->scheme == NULL) ||
- (xmlStrEqual(BAD_CAST puri->scheme, BAD_CAST "file")))
- unescaped = xmlURIUnescapeString(URI, 0, NULL);
- xmlFreeURI(puri);
+ /*
+ * try to limit the damages of the URI unescaping code.
+ */
+ if (puri->scheme == NULL) {
+ unescaped = xmlURIUnescapeString(URI, 0, NULL);
+ if (unescaped == NULL) {
+ xmlFreeURI(puri);
+ return(NULL);
+ }
+ URI = unescaped;
+ }
+ xmlFreeURI(puri);
}
/*
- * Try to find one of the output accept method accepting that scheme
- * Go in reverse to give precedence to user defined handlers.
- * try with an unescaped version of the URI
+ * Allocate the Output buffer front-end.
*/
- if (unescaped != NULL) {
-#ifdef LIBXML_ZLIB_ENABLED
- if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) {
- context = xmlGzfileOpenW(unescaped, compression);
- if (context != NULL) {
- ret = xmlAllocOutputBufferInternal(encoder);
- if (ret != NULL) {
- ret->context = context;
- ret->writecallback = xmlGzfileWrite;
- ret->closecallback = xmlGzfileClose;
- }
- xmlFree(unescaped);
- return(ret);
- }
- }
-#endif
- for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
- if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
- (xmlOutputCallbackTable[i].matchcallback(unescaped) != 0)) {
-#if defined(LIBXML_HTTP_ENABLED) && defined(LIBXML_ZLIB_ENABLED)
- /* Need to pass compression parameter into HTTP open calls */
- if (xmlOutputCallbackTable[i].matchcallback == xmlIOHTTPMatch)
- context = xmlIOHTTPOpenW(unescaped, compression);
- else
-#endif
- context = xmlOutputCallbackTable[i].opencallback(unescaped);
- if (context != NULL)
- break;
- }
- }
- xmlFree(unescaped);
+ ret = xmlAllocOutputBufferInternal(encoder);
+ if (ret == NULL) {
+ xmlFree(unescaped);
+ return(NULL);
}
/*
- * If this failed try with a non-escaped URI this may be a strange
- * filename
+ * Try to find one of the output accept method accepting that scheme
+ * Go in reverse to give precedence to user defined handlers.
*/
- if (context == NULL) {
-#ifdef LIBXML_ZLIB_ENABLED
- if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) {
- context = xmlGzfileOpenW(URI, compression);
- if (context != NULL) {
- ret = xmlAllocOutputBufferInternal(encoder);
- if (ret != NULL) {
- ret->context = context;
- ret->writecallback = xmlGzfileWrite;
- ret->closecallback = xmlGzfileClose;
- }
- else
- xmlGzfileClose(context);
- return(ret);
- }
- }
-#endif
- for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
- if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
- (xmlOutputCallbackTable[i].matchcallback(URI) != 0)) {
-#if defined(LIBXML_HTTP_ENABLED) && defined(LIBXML_ZLIB_ENABLED)
- /* Need to pass compression parameter into HTTP open calls */
- if (xmlOutputCallbackTable[i].matchcallback == xmlIOHTTPMatch)
- context = xmlIOHTTPOpenW(URI, compression);
- else
-#endif
- context = xmlOutputCallbackTable[i].opencallback(URI);
- if (context != NULL)
- break;
- }
- }
- }
+ for (i = xmlOutputCallbackNr - 1; i >= 0; i--) {
+ xmlOutputCallback *cb = &xmlOutputCallbackTable[i];
+ int code;
- if (context == NULL) {
- return(NULL);
+ if (cb->matchcallback == xmlIODefaultMatch) {
+ code = xmlOutputDefaultOpen(ret, URI, compression);
+ /* TODO: Handle other errors */
+ if (code == XML_ERR_OK)
+ break;
+ } else if ((cb->matchcallback != NULL) &&
+ (cb->matchcallback(URI) != 0)) {
+ ret->context = cb->opencallback(URI);
+ if (ret->context != NULL) {
+ ret->writecallback = cb->writecallback;
+ ret->closecallback = cb->closecallback;
+ break;
+ }
+ }
}
- /*
- * Allocate the Output buffer front-end.
- */
- ret = xmlAllocOutputBufferInternal(encoder);
- if (ret != NULL) {
- ret->context = context;
- ret->writecallback = xmlOutputCallbackTable[i].writecallback;
- ret->closecallback = xmlOutputCallbackTable[i].closecallback;
+ if (ret->context == NULL) {
+ xmlOutputBufferClose(ret);
+ ret = NULL;
}
+
+ xmlFree(unescaped);
return(ret);
}
@@ -2709,27 +1787,28 @@ xmlOutputBufferCreateFilename(const char *URI,
/**
* xmlParserInputBufferCreateFile:
* @file: a FILE*
- * @enc: the charset encoding if known
+ * @enc: the charset encoding if known (deprecated)
*
* Create a buffered parser input for the progressive parsing of a FILE *
* buffered C I/O
*
+ * The encoding argument is deprecated and should be set to
+ * XML_CHAR_ENCODING_NONE. The encoding can be changed with
+ * xmlSwitchEncoding or xmlSwitchEncodingName later on.
+ *
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateFile(FILE *file, xmlCharEncoding enc) {
xmlParserInputBufferPtr ret;
- if (xmlInputCallbackInitialized == 0)
- xmlRegisterDefaultInputCallbacks();
-
if (file == NULL) return(NULL);
ret = xmlAllocParserInputBuffer(enc);
if (ret != NULL) {
ret->context = file;
ret->readcallback = xmlFileRead;
- ret->closecallback = xmlFileFlush;
+ ret->closecallback = NULL;
}
return(ret);
@@ -2750,9 +1829,6 @@ xmlOutputBufferPtr
xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) {
xmlOutputBufferPtr ret;
- if (xmlOutputCallbackInitialized == 0)
- xmlRegisterDefaultOutputCallbacks();
-
if (file == NULL) return(NULL);
ret = xmlAllocOutputBufferInternal(encoder);
@@ -2797,7 +1873,7 @@ xmlOutputBufferCreateBuffer(xmlBufferPtr buffer,
*/
const xmlChar *
xmlOutputBufferGetContent(xmlOutputBufferPtr out) {
- if ((out == NULL) || (out->buffer == NULL))
+ if ((out == NULL) || (out->buffer == NULL) || (out->error != 0))
return(NULL);
return(xmlBufContent(out->buffer));
@@ -2813,7 +1889,7 @@ xmlOutputBufferGetContent(xmlOutputBufferPtr out) {
*/
size_t
xmlOutputBufferGetSize(xmlOutputBufferPtr out) {
- if ((out == NULL) || (out->buffer == NULL))
+ if ((out == NULL) || (out->buffer == NULL) || (out->error != 0))
return(0);
return(xmlBufUse(out->buffer));
@@ -2825,11 +1901,15 @@ xmlOutputBufferGetSize(xmlOutputBufferPtr out) {
/**
* xmlParserInputBufferCreateFd:
* @fd: a file descriptor number
- * @enc: the charset encoding if known
+ * @enc: the charset encoding if known (deprecated)
*
* Create a buffered parser input for the progressive parsing for the input
* from a file descriptor
*
+ * The encoding argument is deprecated and should be set to
+ * XML_CHAR_ENCODING_NONE. The encoding can be changed with
+ * xmlSwitchEncoding or xmlSwitchEncodingName later on.
+ *
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
@@ -2842,7 +1922,6 @@ xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
if (ret != NULL) {
ret->context = (void *) (ptrdiff_t) fd;
ret->readcallback = xmlFdRead;
- ret->closecallback = xmlFdClose;
}
return(ret);
@@ -2872,17 +1951,71 @@ static int
xmlMemClose(void *vctxt) {
xmlMemIOCtxt *ctxt = vctxt;
- if (ctxt->mem != 0)
+ if (ctxt->mem != NULL)
xmlFree(ctxt->mem);
xmlFree(ctxt);
return(0);
}
+/**
+ * xmlNewInputBufferMemory:
+ * @mem: memory buffer
+ * @size: size of buffer
+ * @flags: flags
+ * @enc: the charset encoding if known (deprecated)
+ *
+ * Create an input buffer for memory.
+ *
+ * Returns the new input buffer or NULL.
+ */
+xmlParserInputBufferPtr
+xmlNewInputBufferMemory(const void *mem, size_t size, int flags,
+ xmlCharEncoding enc) {
+ xmlParserInputBufferPtr ret;
+ xmlMemIOCtxt *ctxt;
+ char *copy = NULL;
+
+ if ((flags & XML_INPUT_BUF_STATIC) == 0) {
+ if (size + 1 == 0)
+ return(NULL);
+ copy = xmlMalloc(size + 1);
+ if (copy == NULL)
+ return(NULL);
+ memcpy(copy, mem, size);
+ copy[size] = 0;
+
+ mem = copy;
+ }
+
+ ret = xmlAllocParserInputBuffer(enc);
+ if (ret == NULL) {
+ xmlFree(copy);
+ return(NULL);
+ }
+
+ ctxt = xmlMalloc(sizeof(*ctxt));
+ if (ctxt == NULL) {
+ xmlFreeParserInputBuffer(ret);
+ xmlFree(copy);
+ return(NULL);
+ }
+
+ ctxt->mem = copy;
+ ctxt->cur = mem;
+ ctxt->size = size;
+
+ ret->context = ctxt;
+ ret->readcallback = xmlMemRead;
+ ret->closecallback = xmlMemClose;
+
+ return(ret);
+}
+
/**
* xmlParserInputBufferCreateMem:
* @mem: the memory input
* @size: the length of the memory block
- * @enc: the charset encoding if known
+ * @enc: the charset encoding if known (deprecated)
*
* Create a parser input buffer for parsing from a memory area.
*
@@ -2894,32 +2027,15 @@ xmlMemClose(void *vctxt) {
* The encoding argument is deprecated and should be set to
* XML_CHAR_ENCODING_NONE. The encoding can be changed with
* xmlSwitchEncoding or xmlSwitchEncodingName later on.
- *
- * Returns the new parser input or NULL in case of error.
- */
-xmlParserInputBufferPtr
-xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
- xmlParserInputBufferPtr buf;
- xmlMemIOCtxt *ctxt;
- char *copy;
-
- if ((size < 0) || (mem == NULL))
- return(NULL);
-
- copy = (char *) xmlStrndup((const xmlChar *) mem, size);
- if (copy == NULL)
- return(NULL);
-
- buf = xmlParserInputBufferCreateStatic(copy, size, enc);
- if (buf == NULL) {
- xmlFree(copy);
+ *
+ * Returns the new parser input or NULL in case of error.
+ */
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
+ if ((mem == NULL) || (size < 0))
return(NULL);
- }
-
- ctxt = buf->context;
- ctxt->mem = copy;
- return(buf);
+ return(xmlNewInputBufferMemory(mem, size, 0, enc));
}
/**
@@ -2943,40 +2059,20 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
xmlParserInputBufferPtr
xmlParserInputBufferCreateStatic(const char *mem, int size,
xmlCharEncoding enc) {
- xmlParserInputBufferPtr ret;
- xmlMemIOCtxt *ctxt;
-
- if ((size < 0) || (mem == NULL))
- return(NULL);
-
- ret = xmlAllocParserInputBuffer(enc);
- if (ret == NULL)
- return(NULL);
-
- ctxt = xmlMalloc(sizeof(*ctxt));
- if (ctxt == NULL) {
- xmlFreeParserInputBuffer(ret);
+ if ((mem == NULL) || (size < 0))
return(NULL);
- }
- ctxt->mem = NULL;
- ctxt->cur = mem;
- ctxt->size = size;
-
- ret->context = ctxt;
- ret->readcallback = xmlMemRead;
- ret->closecallback = xmlMemClose;
- return(ret);
+ return(xmlNewInputBufferMemory(mem, size, XML_INPUT_BUF_STATIC, enc));
}
typedef struct {
- const xmlChar *str;
+ const char *str;
} xmlStringIOCtxt;
static int
xmlStringRead(void *vctxt, char *buf, int size) {
xmlStringIOCtxt *ctxt = vctxt;
- const xmlChar *zero;
+ const char *zero;
size_t len;
zero = memchr(ctxt->str, 0, size);
@@ -2995,20 +2091,22 @@ xmlStringClose(void *vctxt) {
}
/**
- * xmlParserInputBufferCreateString:
- * @str: a null-terminated string
+ * xmlNewInputBufferString:
+ * @str: C string
+ * @flags: flags
*
- * Create a buffered parser input for the progressive parsing for the input
- * from a null-terminated C string.
+ * Create an input buffer for a null-teriminated C string.
*
- * Returns the new parser input or NULL
+ * Returns the new input buffer or NULL.
*/
xmlParserInputBufferPtr
-xmlParserInputBufferCreateString(const xmlChar *str) {
+xmlNewInputBufferString(const char *str, int flags) {
xmlParserInputBufferPtr ret;
xmlStringIOCtxt *ctxt;
- if (str == NULL) return(NULL);
+ if ((flags & XML_INPUT_BUF_STATIC) == 0)
+ return(xmlNewInputBufferMemory(str, strlen(str), flags,
+ XML_CHAR_ENCODING_NONE));
ret = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
if (ret == NULL)
@@ -3019,6 +2117,7 @@ xmlParserInputBufferCreateString(const xmlChar *str) {
xmlFreeParserInputBuffer(ret);
return(NULL);
}
+
ctxt->str = str;
ret->context = ctxt;
@@ -3061,11 +2160,15 @@ xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
* @ioread: an I/O read function
* @ioclose: an I/O close function
* @ioctx: an I/O handler
- * @enc: the charset encoding if known
+ * @enc: the charset encoding if known (deprecated)
*
* Create a buffered parser input for the progressive parsing for the input
* from an I/O handler
*
+ * The encoding argument is deprecated and should be set to
+ * XML_CHAR_ENCODING_NONE. The encoding can be changed with
+ * xmlSwitchEncoding or xmlSwitchEncodingName later on.
+ *
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
@@ -3274,7 +2377,10 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
if (res <= 0)
in->readcallback = endOfInput;
if (res < 0) {
- in->error = XML_IO_UNKNOWN;
+ if (res == -1)
+ in->error = XML_IO_UNKNOWN;
+ else
+ in->error = -res;
return(-1);
}
@@ -3359,10 +2465,16 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
*/
if (out->conv == NULL) {
out->conv = xmlBufCreate();
+ if (out->conv == NULL) {
+ out->error = XML_ERR_NO_MEMORY;
+ return(-1);
+ }
}
ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk);
- if (ret != 0)
+ if (ret != 0) {
+ out->error = XML_ERR_NO_MEMORY;
return(-1);
+ }
if ((xmlBufUse(out->buffer) < MINLEN) && (chunk == len))
goto done;
@@ -3371,19 +2483,18 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
* convert as much as possible to the parser reading buffer.
*/
ret = xmlCharEncOutput(out, 0);
- if ((ret < 0) && (ret != -3)) {
- xmlIOErr(XML_IO_ENCODER, NULL);
- out->error = XML_IO_ENCODER;
+ if (ret < 0)
return(-1);
- }
if (out->writecallback)
nbchars = xmlBufUse(out->conv);
else
nbchars = ret >= 0 ? ret : 0;
} else {
ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk);
- if (ret != 0)
+ if (ret != 0) {
+ out->error = XML_ERR_NO_MEMORY;
return(-1);
+ }
if (out->writecallback)
nbchars = xmlBufUse(out->buffer);
else
@@ -3411,8 +2522,10 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
xmlBufShrink(out->buffer, ret);
}
if (ret < 0) {
- xmlIOErr(XML_IO_WRITE, NULL);
- out->error = XML_IO_WRITE;
+ int errNo = (ret == -1) ? XML_IO_WRITE : -ret;
+
+ xmlIOErr(errNo, NULL);
+ out->error = errNo;
return(ret);
}
if (out->written > INT_MAX - ret)
@@ -3535,8 +2648,10 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
* not the case force a flush, but make sure we stay in the loop
*/
if (chunk < 40) {
- if (xmlBufGrow(out->buffer, 100) < 0)
+ if (xmlBufGrow(out->buffer, 100) < 0) {
+ out->error = XML_ERR_NO_MEMORY;
return(-1);
+ }
oldwritten = -1;
continue;
}
@@ -3550,11 +2665,17 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
*/
if (out->conv == NULL) {
out->conv = xmlBufCreate();
+ if (out->conv == NULL) {
+ out->error = XML_ERR_NO_MEMORY;
+ return(-1);
+ }
}
ret = escaping(xmlBufEnd(out->buffer) ,
&chunk, str, &cons);
- if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
- return(-1);
+ if (ret < 0) {
+ out->error = XML_ERR_NO_MEMORY;
+ return(-1);
+ }
xmlBufAddLen(out->buffer, chunk);
if ((xmlBufUse(out->buffer) < MINLEN) && (cons == len))
@@ -3564,19 +2685,18 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
* convert as much as possible to the output buffer.
*/
ret = xmlCharEncOutput(out, 0);
- if ((ret < 0) && (ret != -3)) {
- xmlIOErr(XML_IO_ENCODER, NULL);
- out->error = XML_IO_ENCODER;
+ if (ret < 0)
return(-1);
- }
if (out->writecallback)
nbchars = xmlBufUse(out->conv);
else
nbchars = ret >= 0 ? ret : 0;
} else {
ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons);
- if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
- return(-1);
+ if (ret < 0) {
+ out->error = XML_ERR_NO_MEMORY;
+ return(-1);
+ }
xmlBufAddLen(out->buffer, chunk);
if (out->writecallback)
nbchars = xmlBufUse(out->buffer);
@@ -3605,16 +2725,20 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
xmlBufShrink(out->buffer, ret);
}
if (ret < 0) {
- xmlIOErr(XML_IO_WRITE, NULL);
- out->error = XML_IO_WRITE;
- return(ret);
+ int errNo = (ret == -1) ? XML_IO_WRITE : -ret;
+ xmlIOErr(errNo, NULL);
+ out->error = errNo;
+ return(-1);
}
if (out->written > INT_MAX - ret)
out->written = INT_MAX;
else
out->written += ret;
} else if (xmlBufAvail(out->buffer) < MINLEN) {
- xmlBufGrow(out->buffer, MINLEN);
+ if (xmlBufGrow(out->buffer, MINLEN) < 0) {
+ out->error = XML_ERR_NO_MEMORY;
+ return(-1);
+ }
}
written += nbchars;
} while ((len > 0) && (oldwritten != written));
@@ -3650,6 +2774,56 @@ xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
return(len);
}
+/**
+ * xmlOutputBufferWriteQuotedString:
+ * @buf: output buffer
+ * @string: the string to add
+ *
+ * routine which manage and grows an output buffer. This one writes
+ * a quoted or double quoted #xmlChar string, checking first if it holds
+ * quote or double-quotes internally
+ */
+void
+xmlOutputBufferWriteQuotedString(xmlOutputBufferPtr buf,
+ const xmlChar *string) {
+ const xmlChar *cur, *base;
+
+ if ((buf == NULL) || (buf->error))
+ return;
+
+ if (xmlStrchr(string, '\"')) {
+ if (xmlStrchr(string, '\'')) {
+ xmlOutputBufferWrite(buf, 1, "\"");
+ base = cur = string;
+ while(*cur != 0){
+ if(*cur == '"'){
+ if (base != cur)
+ xmlOutputBufferWrite(buf, cur - base,
+ (const char *) base);
+ xmlOutputBufferWrite(buf, 6, """);
+ cur++;
+ base = cur;
+ }
+ else {
+ cur++;
+ }
+ }
+ if (base != cur)
+ xmlOutputBufferWrite(buf, cur - base, (const char *) base);
+ xmlOutputBufferWrite(buf, 1, "\"");
+ }
+ else{
+ xmlOutputBufferWrite(buf, 1, "'");
+ xmlOutputBufferWriteString(buf, (const char *) string);
+ xmlOutputBufferWrite(buf, 1, "'");
+ }
+ } else {
+ xmlOutputBufferWrite(buf, 1, "\"");
+ xmlOutputBufferWriteString(buf, (const char *) string);
+ xmlOutputBufferWrite(buf, 1, "\"");
+ }
+}
+
/**
* xmlOutputBufferFlush:
* @out: a buffered output
@@ -3672,11 +2846,8 @@ xmlOutputBufferFlush(xmlOutputBufferPtr out) {
*/
do {
nbchars = xmlCharEncOutput(out, 0);
- if (nbchars < 0) {
- xmlIOErr(XML_IO_ENCODER, NULL);
- out->error = XML_IO_ENCODER;
+ if (nbchars < 0)
return(-1);
- }
} while (nbchars);
}
@@ -3698,8 +2869,10 @@ xmlOutputBufferFlush(xmlOutputBufferPtr out) {
xmlBufShrink(out->buffer, ret);
}
if (ret < 0) {
- xmlIOErr(XML_IO_FLUSH, NULL);
- out->error = XML_IO_FLUSH;
+ int errNo = (ret == -1) ? XML_IO_WRITE : -ret;
+
+ xmlIOErr(errNo, NULL);
+ out->error = errNo;
return(ret);
}
if (out->written > INT_MAX - ret)
@@ -3725,9 +2898,6 @@ xmlParserGetDirectory(const char *filename) {
char dir[1024];
char *cur;
- if (xmlInputCallbackInitialized == 0)
- xmlRegisterDefaultInputCallbacks();
-
if (filename == NULL) return(NULL);
#if defined(_WIN32)
@@ -3757,332 +2927,202 @@ xmlParserGetDirectory(const char *filename) {
#undef IS_XMLPGD_SEP
}
-/****************************************************************
- * *
- * External entities loading *
- * *
- ****************************************************************/
-
/**
- * xmlCheckHTTPInput:
- * @ctxt: an XML parser context
- * @ret: an XML parser input
+ * xmlNoNetExists:
+ * @filename: the path to check
+ *
+ * DEPRECATED: Internal function, don't use.
*
- * Check an input in case it was created from an HTTP stream, in that
- * case it will handle encoding and update of the base URL in case of
- * redirection. It also checks for HTTP errors in which case the input
- * is cleanly freed up and an appropriate error is raised in context
+ * Like xmlCheckFilename but handles file URIs.
*
- * Returns the input or NULL in case of HTTP error.
+ * Returns 0, 1, or 2.
*/
-xmlParserInputPtr
-xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) {
- /* Avoid unused variable warning if features are disabled. */
- (void) ctxt;
+int
+xmlNoNetExists(const char *filename) {
+ char *fromUri;
+ int ret;
-#ifdef LIBXML_HTTP_ENABLED
- if ((ret != NULL) && (ret->buf != NULL) &&
- (ret->buf->readcallback == xmlIOHTTPRead) &&
- (ret->buf->context != NULL)) {
- const char *encoding;
- const char *redir;
- const char *mime;
- int code;
+ if (filename == NULL)
+ return(0);
- code = xmlNanoHTTPReturnCode(ret->buf->context);
- if (code >= 400) {
- /* fatal error */
- if (ret->filename != NULL)
- __xmlLoaderErr(ctxt, "failed to load HTTP resource \"%s\"\n",
- (const char *) ret->filename);
- else
- __xmlLoaderErr(ctxt, "failed to load HTTP resource\n", NULL);
- xmlFreeInputStream(ret);
- ret = NULL;
- } else {
+ if (xmlConvertUriToPath(filename, &fromUri) < 0)
+ return(0);
- mime = xmlNanoHTTPMimeType(ret->buf->context);
- if ((xmlStrstr(BAD_CAST mime, BAD_CAST "/xml")) ||
- (xmlStrstr(BAD_CAST mime, BAD_CAST "+xml"))) {
- encoding = xmlNanoHTTPEncoding(ret->buf->context);
- if (encoding != NULL) {
- xmlCharEncodingHandlerPtr handler;
-
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler != NULL) {
- xmlSwitchInputEncoding(ctxt, ret, handler);
- } else {
- __xmlErrEncoding(ctxt, XML_ERR_UNKNOWN_ENCODING,
- "Unknown encoding %s",
- BAD_CAST encoding, NULL);
- }
- }
-#if 0
- } else if (xmlStrstr(BAD_CAST mime, BAD_CAST "html")) {
-#endif
- }
- redir = xmlNanoHTTPRedir(ret->buf->context);
- if (redir != NULL) {
- if (ret->filename != NULL)
- xmlFree((xmlChar *) ret->filename);
- if (ret->directory != NULL) {
- xmlFree((xmlChar *) ret->directory);
- ret->directory = NULL;
- }
- ret->filename =
- (char *) xmlStrdup((const xmlChar *) redir);
- }
- }
- }
-#endif
+ if (fromUri != NULL)
+ filename = fromUri;
+
+ ret = xmlCheckFilename(filename);
+
+ xmlFree(fromUri);
return(ret);
}
-static int xmlNoNetExists(const char *URL) {
- const char *path;
+/************************************************************************
+ * *
+ * Input/output callbacks *
+ * *
+ ************************************************************************/
- if (URL == NULL)
- return(0);
+/**
+ * xmlInitIOCallbacks:
+ *
+ * Initialize callback tables.
+ */
+void
+xmlInitIOCallbacks(void)
+{
+ xmlInputCallbackNr = 1;
+ xmlInputCallbackTable[0].matchcallback = xmlIODefaultMatch;
- if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32)
- path = &URL[17];
-#else
- path = &URL[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32)
- path = &URL[8];
-#else
- path = &URL[7];
+#ifdef LIBXML_OUTPUT_ENABLED
+ xmlOutputCallbackNr = 1;
+ xmlOutputCallbackTable[0].matchcallback = xmlIODefaultMatch;
#endif
- } else
- path = URL;
-
- return xmlCheckFilename(path);
}
-#ifdef LIBXML_CATALOG_ENABLED
-
/**
- * xmlResolveResourceFromCatalog:
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @ctxt: the context in which the entity is called or NULL
+ * xmlRegisterInputCallbacks:
+ * @matchFunc: the xmlInputMatchCallback
+ * @openFunc: the xmlInputOpenCallback
+ * @readFunc: the xmlInputReadCallback
+ * @closeFunc: the xmlInputCloseCallback
*
- * Resolves the URL and ID against the appropriate catalog.
- * This function is used by xmlDefaultExternalEntityLoader and
- * xmlNoNetExternalEntityLoader.
+ * Register a new set of I/O callback for handling parser input.
*
- * Returns a new allocated URL, or NULL.
+ * Returns the registered handler number or -1 in case of error
*/
-static xmlChar *
-xmlResolveResourceFromCatalog(const char *URL, const char *ID,
- xmlParserCtxtPtr ctxt) {
- xmlChar *resource = NULL;
- xmlCatalogAllow pref;
-
- /*
- * If the resource doesn't exists as a file,
- * try to load it from the resource pointed in the catalogs
- */
- pref = xmlCatalogGetDefaults();
-
- if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) {
- /*
- * Do a local lookup
- */
- if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- resource = xmlCatalogLocalResolve(ctxt->catalogs,
- (const xmlChar *)ID,
- (const xmlChar *)URL);
- }
- /*
- * Try a global lookup
- */
- if ((resource == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- resource = xmlCatalogResolve((const xmlChar *)ID,
- (const xmlChar *)URL);
- }
- if ((resource == NULL) && (URL != NULL))
- resource = xmlStrdup((const xmlChar *) URL);
-
- /*
- * TODO: do an URI lookup on the reference
- */
- if ((resource != NULL) && (!xmlNoNetExists((const char *)resource))) {
- xmlChar *tmp = NULL;
-
- if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource);
- }
- if ((tmp == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- tmp = xmlCatalogResolveURI(resource);
- }
-
- if (tmp != NULL) {
- xmlFree(resource);
- resource = tmp;
- }
- }
+int
+xmlRegisterInputCallbacks(xmlInputMatchCallback matchFunc,
+ xmlInputOpenCallback openFunc, xmlInputReadCallback readFunc,
+ xmlInputCloseCallback closeFunc) {
+ if (xmlInputCallbackNr >= MAX_INPUT_CALLBACK) {
+ return(-1);
}
-
- return resource;
+ xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = matchFunc;
+ xmlInputCallbackTable[xmlInputCallbackNr].opencallback = openFunc;
+ xmlInputCallbackTable[xmlInputCallbackNr].readcallback = readFunc;
+ xmlInputCallbackTable[xmlInputCallbackNr].closecallback = closeFunc;
+ return(xmlInputCallbackNr++);
}
-#endif
+/**
+ * xmlRegisterDefaultInputCallbacks:
+ *
+ * Registers the default compiled-in I/O handlers.
+ */
+void
+xmlRegisterDefaultInputCallbacks(void) {
+ xmlRegisterInputCallbacks(xmlIODefaultMatch, NULL, NULL, NULL);
+}
/**
- * xmlDefaultExternalEntityLoader:
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @ctxt: the context in which the entity is called or NULL
+ * xmlPopInputCallbacks:
*
- * By default we don't load external entities, yet.
+ * Clear the top input callback from the input stack. this includes the
+ * compiled-in I/O.
*
- * Returns a new allocated xmlParserInputPtr, or NULL.
+ * Returns the number of input callback registered or -1 in case of error.
*/
-static xmlParserInputPtr
-xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
- xmlParserCtxtPtr ctxt)
+int
+xmlPopInputCallbacks(void)
{
- xmlParserInputPtr ret = NULL;
- xmlChar *resource = NULL;
-
- if ((ctxt != NULL) && (ctxt->options & XML_PARSE_NONET)) {
- int options = ctxt->options;
-
- ctxt->options -= XML_PARSE_NONET;
- ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
- ctxt->options = options;
- return(ret);
- }
-#ifdef LIBXML_CATALOG_ENABLED
- resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
-#endif
+ if (xmlInputCallbackNr <= 0)
+ return(-1);
- if (resource == NULL)
- resource = (xmlChar *) URL;
+ xmlInputCallbackNr--;
- if (resource == NULL) {
- if (ID == NULL)
- ID = "NULL";
- __xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n", ID);
- return (NULL);
- }
- ret = xmlNewInputFromFile(ctxt, (const char *) resource);
- if ((resource != NULL) && (resource != (xmlChar *) URL))
- xmlFree(resource);
- return (ret);
+ return(xmlInputCallbackNr);
}
-static xmlExternalEntityLoader xmlCurrentExternalEntityLoader =
- xmlDefaultExternalEntityLoader;
-
/**
- * xmlSetExternalEntityLoader:
- * @f: the new entity resolver function
+ * xmlCleanupInputCallbacks:
*
- * Changes the defaultexternal entity resolver function for the application
+ * clears the entire input callback table. this includes the
+ * compiled-in I/O.
*/
void
-xmlSetExternalEntityLoader(xmlExternalEntityLoader f) {
- xmlCurrentExternalEntityLoader = f;
+xmlCleanupInputCallbacks(void)
+{
+ xmlInputCallbackNr = 0;
}
+#ifdef LIBXML_OUTPUT_ENABLED
/**
- * xmlGetExternalEntityLoader:
+ * xmlRegisterOutputCallbacks:
+ * @matchFunc: the xmlOutputMatchCallback
+ * @openFunc: the xmlOutputOpenCallback
+ * @writeFunc: the xmlOutputWriteCallback
+ * @closeFunc: the xmlOutputCloseCallback
+ *
+ * Register a new set of I/O callback for handling output.
*
- * Get the default external entity resolver function for the application
+ * Returns the registered handler number or -1 in case of error
+ */
+int
+xmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc,
+ xmlOutputOpenCallback openFunc, xmlOutputWriteCallback writeFunc,
+ xmlOutputCloseCallback closeFunc) {
+ if (xmlOutputCallbackNr >= MAX_OUTPUT_CALLBACK) {
+ return(-1);
+ }
+ xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = matchFunc;
+ xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = openFunc;
+ xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = writeFunc;
+ xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = closeFunc;
+ return(xmlOutputCallbackNr++);
+}
+
+/**
+ * xmlRegisterDefaultOutputCallbacks:
*
- * Returns the xmlExternalEntityLoader function pointer
+ * Registers the default compiled-in I/O handlers.
*/
-xmlExternalEntityLoader
-xmlGetExternalEntityLoader(void) {
- return(xmlCurrentExternalEntityLoader);
+void
+xmlRegisterDefaultOutputCallbacks (void) {
+ xmlRegisterOutputCallbacks(xmlIODefaultMatch, NULL, NULL, NULL);
}
/**
- * xmlLoadExternalEntity:
- * @URL: the URL for the entity to load
- * @ID: the Public ID for the entity to load
- * @ctxt: the context in which the entity is called or NULL
+ * xmlPopOutputCallbacks:
*
- * Load an external entity, note that the use of this function for
- * unparsed entities may generate problems
+ * Remove the top output callbacks from the output stack. This includes the
+ * compiled-in I/O.
*
- * Returns the xmlParserInputPtr or NULL
+ * Returns the number of output callback registered or -1 in case of error.
*/
-xmlParserInputPtr
-xmlLoadExternalEntity(const char *URL, const char *ID,
- xmlParserCtxtPtr ctxt) {
- if ((URL != NULL) && (xmlNoNetExists(URL) == 0)) {
- char *canonicFilename;
- xmlParserInputPtr ret;
+int
+xmlPopOutputCallbacks(void)
+{
+ if (xmlOutputCallbackNr <= 0)
+ return(-1);
- canonicFilename = (char *) xmlCanonicPath((const xmlChar *) URL);
- if (canonicFilename == NULL) {
- xmlErrMemory(ctxt, "building canonical path\n");
- return(NULL);
- }
+ xmlOutputCallbackNr--;
- ret = xmlCurrentExternalEntityLoader(canonicFilename, ID, ctxt);
- xmlFree(canonicFilename);
- return(ret);
- }
- return(xmlCurrentExternalEntityLoader(URL, ID, ctxt));
+ return(xmlOutputCallbackNr);
}
-/************************************************************************
- * *
- * Disabling Network access *
- * *
- ************************************************************************/
-
/**
- * xmlNoNetExternalEntityLoader:
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @ctxt: the context in which the entity is called or NULL
- *
- * A specific entity loader disabling network accesses, though still
- * allowing local catalog accesses for resolution.
+ * xmlCleanupOutputCallbacks:
*
- * Returns a new allocated xmlParserInputPtr, or NULL.
+ * clears the entire output callback table. this includes the
+ * compiled-in I/O callbacks.
*/
-xmlParserInputPtr
-xmlNoNetExternalEntityLoader(const char *URL, const char *ID,
- xmlParserCtxtPtr ctxt) {
- xmlParserInputPtr input = NULL;
- xmlChar *resource = NULL;
-
-#ifdef LIBXML_CATALOG_ENABLED
- resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
-#endif
-
- if (resource == NULL)
- resource = (xmlChar *) URL;
+void
+xmlCleanupOutputCallbacks(void)
+{
+ xmlOutputCallbackNr = 0;
+}
- if (resource != NULL) {
- if ((!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "ftp://", 6)) ||
- (!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "http://", 7))) {
- xmlIOErr(XML_IO_NETWORK_ATTEMPT, (const char *) resource);
- if (resource != (xmlChar *) URL)
- xmlFree(resource);
- return(NULL);
- }
- }
- input = xmlDefaultExternalEntityLoader((const char *) resource, ID, ctxt);
- if (resource != (xmlChar *) URL)
- xmlFree(resource);
- return(input);
+#ifdef LIBXML_HTTP_ENABLED
+/**
+ * xmlRegisterHTTPPostCallbacks:
+ *
+ * DEPRECATED: Support for HTTP POST has been removed.
+ */
+void
+xmlRegisterHTTPPostCallbacks(void) {
+ xmlRegisterDefaultOutputCallbacks();
}
+#endif
+#endif /* LIBXML_OUTPUT_ENABLED */
diff --git a/xmllint.c b/xmllint.c
index 9620007..3d17c37 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -84,10 +84,20 @@
#include
#endif
+#ifdef XMLLINT_FUZZ
+ #define ERR_STREAM stdout
+#else
+ #define ERR_STREAM stderr
+#endif
+
#ifndef XML_XML_DEFAULT_CATALOG
#define XML_XML_DEFAULT_CATALOG "file://" SYSCONFDIR "/xml/catalog"
#endif
+#ifndef STDIN_FILENO
+ #define STDIN_FILENO 0
+#endif
+
typedef enum {
XMLLINT_RETURN_OK = 0, /* No error */
XMLLINT_ERR_UNCLASS = 1, /* Unclassified */
@@ -97,11 +107,12 @@ typedef enum {
XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */
XMLLINT_ERR_OUT = 6, /* Error writing output */
XMLLINT_ERR_SCHEMAPAT = 7, /* Error in schema pattern */
- XMLLINT_ERR_RDREGIS = 8, /* Error in Reader registration */
+ /*XMLLINT_ERR_RDREGIS = 8,*/
XMLLINT_ERR_MEM = 9, /* Out of memory error */
XMLLINT_ERR_XPATH = 10, /* XPath evaluation error */
XMLLINT_ERR_XPATH_EMPTY = 11 /* XPath result is empty */
} xmllintReturnCode;
+
#ifdef LIBXML_DEBUG_ENABLED
static int shell = 0;
static int debugent = 0;
@@ -111,44 +122,35 @@ static int maxmem = 0;
#ifdef LIBXML_TREE_ENABLED
static int copy = 0;
#endif /* LIBXML_TREE_ENABLED */
-static int recovery = 0;
-static int noent = 0;
-static int noenc = 0;
-static int noblanks = 0;
static int noout = 0;
-static int nowrap = 0;
-static int format = 0;
#ifdef LIBXML_OUTPUT_ENABLED
static const char *output = NULL;
+static int format = 0;
+static const char *encoding = NULL;
static int compress = 0;
-static int oldout = 0;
#endif /* LIBXML_OUTPUT_ENABLED */
#ifdef LIBXML_VALID_ENABLED
-static int valid = 0;
static int postvalid = 0;
-static char * dtdvalid = NULL;
-static char * dtdvalidfpi = NULL;
+static const char *dtdvalid = NULL;
+static const char *dtdvalidfpi = NULL;
+static int insert = 0;
#endif
#ifdef LIBXML_SCHEMAS_ENABLED
-static char * relaxng = NULL;
+static const char *relaxng = NULL;
static xmlRelaxNGPtr relaxngschemas = NULL;
-static char * schema = NULL;
+static const char *schema = NULL;
static xmlSchemaPtr wxschemas = NULL;
#endif
#ifdef LIBXML_SCHEMATRON_ENABLED
-static char * schematron = NULL;
+static const char *schematron = NULL;
static xmlSchematronPtr wxschematron = NULL;
#endif
static int repeat = 0;
-static int insert = 0;
-#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
+#if defined(LIBXML_HTML_ENABLED)
static int html = 0;
static int xmlout = 0;
#endif
static int htmlout = 0;
-#if defined(LIBXML_HTML_ENABLED)
-static int nodefdtd = 0;
-#endif
#ifdef LIBXML_PUSH_ENABLED
static int push = 0;
static int pushsize = 4096;
@@ -157,28 +159,20 @@ static int pushsize = 4096;
static int memory = 0;
#endif
static int testIO = 0;
-static char *encoding = NULL;
#ifdef LIBXML_XINCLUDE_ENABLED
static int xinclude = 0;
#endif
-static int dtdattrs = 0;
-static int loaddtd = 0;
static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
static int quiet = 0;
static int timing = 0;
static int generate = 0;
static int dropdtd = 0;
-#ifdef LIBXML_CATALOG_ENABLED
-static int catalogs = 0;
-static int nocatalogs = 0;
-#endif
#ifdef LIBXML_C14N_ENABLED
static int canonical = 0;
static int canonical_11 = 0;
static int exc_canonical = 0;
#endif
#ifdef LIBXML_READER_ENABLED
-static int stream = 0;
static int walker = 0;
#ifdef LIBXML_PATTERN_ENABLED
static const char *pattern = NULL;
@@ -186,17 +180,10 @@ static xmlPatternPtr patternc = NULL;
static xmlStreamCtxtPtr patstream = NULL;
#endif
#endif /* LIBXML_READER_ENABLED */
-static int chkregister = 0;
-static int nbregister = 0;
-#ifdef LIBXML_SAX1_ENABLED
-static int sax1 = 0;
-#endif /* LIBXML_SAX1_ENABLED */
#ifdef LIBXML_XPATH_ENABLED
static const char *xpathquery = NULL;
#endif
static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
-static int sax = 0;
-static int oldxml10 = 0;
static unsigned maxAmpl = 0;
/************************************************************************
@@ -222,7 +209,7 @@ void parsePath(const xmlChar *path) {
return;
while (*path != 0) {
if (nbpaths >= MAX_PATHS) {
- fprintf(stderr, "MAX_PATHS reached: too many paths\n");
+ fprintf(ERR_STREAM, "MAX_PATHS reached: too many paths\n");
return;
}
cur = path;
@@ -277,7 +264,7 @@ xmllintExternalEntityLoader(const char *URL, const char *ID,
ctxt->sax->error = err;
if (load_trace) {
fprintf \
- (stderr,
+ (ERR_STREAM,
"Loaded URL=\"%s\" ID=\"%s\"\n",
URL ? URL : "(null)",
ID ? ID : "(null)");
@@ -300,7 +287,7 @@ xmllintExternalEntityLoader(const char *URL, const char *ID,
ctxt->sax->error = err;
if (load_trace) {
fprintf \
- (stderr,
+ (ERR_STREAM,
"Loaded URL=\"%s\" ID=\"%s\"\n",
newURL,
ID ? ID : "(null)");
@@ -322,6 +309,7 @@ xmllintExternalEntityLoader(const char *URL, const char *ID,
}
return(NULL);
}
+
/************************************************************************
* *
* Memory allocation consumption debugging *
@@ -331,7 +319,7 @@ xmllintExternalEntityLoader(const char *URL, const char *ID,
static void
OOM(void)
{
- fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
+ fprintf(ERR_STREAM, "Ran out of memory needs > %d bytes\n", maxmem);
progresult = XMLLINT_ERR_MEM;
}
@@ -376,7 +364,7 @@ myStrdupFunc(const char *str)
if (ret != NULL) {
if (xmlMemUsed() > maxmem) {
OOM();
- xmlFree(ret);
+ xmlMemFree(ret);
return (NULL);
}
}
@@ -443,10 +431,10 @@ endTimer(const char *fmt, ...)
msec += (end.tv_usec - begin.tv_usec) / 1000;
va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
+ vfprintf(ERR_STREAM, fmt, ap);
va_end(ap);
- fprintf(stderr, " took %ld ms\n", msec);
+ fprintf(ERR_STREAM, " took %ld ms\n", msec);
}
#else
/*
@@ -474,9 +462,9 @@ endTimer(const char *fmt, ...)
msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
+ vfprintf(ERR_STREAM, fmt, ap);
va_end(ap);
- fprintf(stderr, " took %ld ms\n", msec);
+ fprintf(ERR_STREAM, " took %ld ms\n", msec);
}
#endif
/************************************************************************
@@ -498,7 +486,7 @@ xmlHTMLEncodeSend(void) {
memset(&buffer[sizeof(buffer)-4], 0, 4);
result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
if (result) {
- xmlGenericError(xmlGenericErrorContext, "%s", result);
+ fprintf(ERR_STREAM, "%s", result);
xmlFree(result);
}
buffer[0] = 0;
@@ -514,7 +502,7 @@ xmlHTMLEncodeSend(void) {
static void
xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
int len;
- xmlGenericError(xmlGenericErrorContext, "");
+ fprintf(ERR_STREAM, "
");
len = strlen(buffer);
if (input != NULL) {
@@ -542,7 +530,7 @@ xmlHTMLPrintFileContext(xmlParserInputPtr input) {
int n;
if (input == NULL) return;
- xmlGenericError(xmlGenericErrorContext, "
\n");
+ fprintf(ERR_STREAM, "\n");
cur = input->cur;
base = input->base;
while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
@@ -574,7 +562,7 @@ xmlHTMLPrintFileContext(xmlParserInputPtr input) {
len = strlen(buffer);
snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
xmlHTMLEncodeSend();
- xmlGenericError(xmlGenericErrorContext, "
");
+ fprintf(ERR_STREAM, "
");
}
/**
@@ -602,13 +590,13 @@ xmlHTMLError(void *ctx, const char *msg, ...)
xmlHTMLPrintFileInfo(input);
- xmlGenericError(xmlGenericErrorContext, "error: ");
+ fprintf(ERR_STREAM, "error: ");
va_start(args, msg);
len = strlen(buffer);
vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
va_end(args);
xmlHTMLEncodeSend();
- xmlGenericError(xmlGenericErrorContext, "
\n");
+ fprintf(ERR_STREAM, "\n");
xmlHTMLPrintFileContext(input);
xmlHTMLEncodeSend();
@@ -640,13 +628,13 @@ xmlHTMLWarning(void *ctx, const char *msg, ...)
xmlHTMLPrintFileInfo(input);
- xmlGenericError(xmlGenericErrorContext, "warning: ");
+ fprintf(ERR_STREAM, "warning: ");
va_start(args, msg);
len = strlen(buffer);
vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
va_end(args);
xmlHTMLEncodeSend();
- xmlGenericError(xmlGenericErrorContext, "\n");
+ fprintf(ERR_STREAM, "\n");
xmlHTMLPrintFileContext(input);
xmlHTMLEncodeSend();
@@ -671,20 +659,24 @@ xmlHTMLValidityError(void *ctx, const char *msg, ...)
buffer[0] = 0;
input = ctxt->input;
- if ((input->filename == NULL) && (ctxt->inputNr > 1))
- input = ctxt->inputTab[ctxt->inputNr - 2];
- xmlHTMLPrintFileInfo(input);
+ if (input != NULL) {
+ if ((input->filename == NULL) && (ctxt->inputNr > 1))
+ input = ctxt->inputTab[ctxt->inputNr - 2];
- xmlGenericError(xmlGenericErrorContext, "validity error: ");
+ xmlHTMLPrintFileInfo(input);
+ }
+
+ fprintf(ERR_STREAM, "validity error: ");
len = strlen(buffer);
va_start(args, msg);
vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
va_end(args);
xmlHTMLEncodeSend();
- xmlGenericError(xmlGenericErrorContext, "\n");
+ fprintf(ERR_STREAM, "\n");
- xmlHTMLPrintFileContext(input);
+ if (input != NULL)
+ xmlHTMLPrintFileContext(input);
xmlHTMLEncodeSend();
progresult = XMLLINT_ERR_VALID;
}
@@ -713,13 +705,13 @@ xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
xmlHTMLPrintFileInfo(input);
- xmlGenericError(xmlGenericErrorContext, "validity warning: ");
+ fprintf(ERR_STREAM, "validity warning: ");
va_start(args, msg);
len = strlen(buffer);
vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
va_end(args);
xmlHTMLEncodeSend();
- xmlGenericError(xmlGenericErrorContext, "\n");
+ fprintf(ERR_STREAM, "\n");
xmlHTMLPrintFileContext(input);
xmlHTMLEncodeSend();
@@ -1250,7 +1242,7 @@ charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
if (noout)
return;
for (i = 0;(i 0) {
- fprintf(stderr, "%s fails to validate\n", filename);
+ fprintf(ERR_STREAM, "%s fails to validate\n", filename);
progresult = XMLLINT_ERR_VALID;
} else {
- fprintf(stderr, "%s validation generated an internal error\n",
+ fprintf(ERR_STREAM, "%s validation generated an internal error\n",
filename);
progresult = XMLLINT_ERR_VALID;
}
@@ -1654,10 +1649,14 @@ testSAX(const char *filename) {
}
if (maxAmpl > 0)
xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
- xmlCtxtReadFile(ctxt, filename, NULL, options);
+
+ if (strcmp(filename, "-") == 0)
+ xmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL, options);
+ else
+ xmlCtxtReadFile(ctxt, filename, NULL, options);
if (ctxt->myDoc != NULL) {
- fprintf(stderr, "SAX generated a doc !\n");
+ fprintf(ERR_STREAM, "SAX generated a doc !\n");
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
}
@@ -1725,7 +1724,7 @@ static void processNode(xmlTextReaderPtr reader) {
xmlTextReaderConstLocalName(reader),
xmlTextReaderConstNamespaceUri(reader));
if (ret < 0) {
- fprintf(stderr, "xmlStreamPush() failure\n");
+ fprintf(ERR_STREAM, "xmlStreamPush() failure\n");
xmlFreeStreamCtxt(patstream);
patstream = NULL;
} else if (ret != match) {
@@ -1735,13 +1734,13 @@ static void processNode(xmlTextReaderPtr reader) {
xmlTextReaderCurrentNode(reader));
}
#endif
- fprintf(stderr,
+ fprintf(ERR_STREAM,
"xmlPatternMatch and xmlStreamPush disagree\n");
if (path != NULL)
- fprintf(stderr, " pattern %s node %s\n",
+ fprintf(ERR_STREAM, " pattern %s node %s\n",
pattern, path);
else
- fprintf(stderr, " pattern %s node %s\n",
+ fprintf(ERR_STREAM, " pattern %s node %s\n",
pattern, xmlTextReaderConstName(reader));
}
@@ -1750,7 +1749,7 @@ static void processNode(xmlTextReaderPtr reader) {
((type == XML_READER_TYPE_ELEMENT) && (empty))) {
ret = xmlStreamPop(patstream);
if (ret < 0) {
- fprintf(stderr, "xmlStreamPop() failure\n");
+ fprintf(ERR_STREAM, "xmlStreamPop() failure\n");
xmlFreeStreamCtxt(patstream);
patstream = NULL;
}
@@ -1762,14 +1761,13 @@ static void processNode(xmlTextReaderPtr reader) {
#endif
}
-static void streamFile(char *filename) {
+static void streamFile(const char *filename) {
xmlTextReaderPtr reader;
int ret;
#ifdef HAVE_MMAP
int fd = -1;
struct stat info;
const char *base = NULL;
- xmlParserInputBufferPtr input = NULL;
if (memory) {
if (stat(filename, &info) < 0)
@@ -1779,7 +1777,7 @@ static void streamFile(char *filename) {
base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
if (base == (void *) MAP_FAILED) {
close(fd);
- fprintf(stderr, "mmap failure for file %s\n", filename);
+ fprintf(ERR_STREAM, "mmap failure for file %s\n", filename);
progresult = XMLLINT_ERR_RDFILE;
return;
}
@@ -1788,6 +1786,9 @@ static void streamFile(char *filename) {
NULL, options);
} else
#endif
+ if (strcmp(filename, "-") == 0)
+ reader = xmlReaderForFd(STDIN_FILENO, "-", NULL, options);
+ else
reader = xmlReaderForFile(filename, NULL, options);
#ifdef LIBXML_PATTERN_ENABLED
if (patternc != NULL) {
@@ -1795,7 +1796,7 @@ static void streamFile(char *filename) {
if (patstream != NULL) {
ret = xmlStreamPush(patstream, NULL, NULL);
if (ret < 0) {
- fprintf(stderr, "xmlStreamPush() failure\n");
+ fprintf(ERR_STREAM, "xmlStreamPush() failure\n");
xmlFreeStreamCtxt(patstream);
patstream = NULL;
}
@@ -1807,13 +1808,6 @@ static void streamFile(char *filename) {
if (reader != NULL) {
if (maxAmpl > 0)
xmlTextReaderSetMaxAmplification(reader, maxAmpl);
-#ifdef LIBXML_VALID_ENABLED
- if (valid)
- xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
- else
-#endif /* LIBXML_VALID_ENABLED */
- if (loaddtd)
- xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
#ifdef LIBXML_SCHEMAS_ENABLED
if (relaxng != NULL) {
if ((timing) && (!repeat)) {
@@ -1821,7 +1815,7 @@ static void streamFile(char *filename) {
}
ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
if (ret < 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Relax-NG schema %s failed to compile\n", relaxng);
progresult = XMLLINT_ERR_SCHEMACOMP;
relaxng = NULL;
@@ -1836,7 +1830,7 @@ static void streamFile(char *filename) {
}
ret = xmlTextReaderSchemaValidate(reader, schema);
if (ret < 0) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"XSD schema %s failed to compile\n", schema);
progresult = XMLLINT_ERR_SCHEMACOMP;
schema = NULL;
@@ -1870,7 +1864,7 @@ static void streamFile(char *filename) {
else
#endif
#ifdef LIBXML_VALID_ENABLED
- if (valid)
+ if (options & XML_PARSE_DTDVALID)
endTimer("Parsing and validating");
else
#endif
@@ -1878,9 +1872,9 @@ static void streamFile(char *filename) {
}
#ifdef LIBXML_VALID_ENABLED
- if (valid) {
+ if (options & XML_PARSE_DTDVALID) {
if (xmlTextReaderIsValid(reader) != 1) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Document %s does not validate\n", filename);
progresult = XMLLINT_ERR_VALID;
}
@@ -1889,11 +1883,11 @@ static void streamFile(char *filename) {
#ifdef LIBXML_SCHEMAS_ENABLED
if ((relaxng != NULL) || (schema != NULL)) {
if (xmlTextReaderIsValid(reader) != 1) {
- fprintf(stderr, "%s fails to validate\n", filename);
+ fprintf(ERR_STREAM, "%s fails to validate\n", filename);
progresult = XMLLINT_ERR_VALID;
} else {
if (!quiet) {
- fprintf(stderr, "%s validates\n", filename);
+ fprintf(ERR_STREAM, "%s validates\n", filename);
}
}
}
@@ -1903,11 +1897,11 @@ static void streamFile(char *filename) {
*/
xmlFreeTextReader(reader);
if (ret != 0) {
- fprintf(stderr, "%s : failed to parse\n", filename);
+ fprintf(ERR_STREAM, "%s : failed to parse\n", filename);
progresult = XMLLINT_ERR_UNCLASS;
}
} else {
- fprintf(stderr, "Unable to open %s\n", filename);
+ fprintf(ERR_STREAM, "Unable to open %s\n", filename);
progresult = XMLLINT_ERR_UNCLASS;
}
#ifdef LIBXML_PATTERN_ENABLED
@@ -1918,7 +1912,6 @@ static void streamFile(char *filename) {
#endif
#ifdef HAVE_MMAP
if (memory) {
- xmlFreeParserInputBuffer(input);
munmap((char *) base, info.st_size);
close(fd);
}
@@ -1930,45 +1923,51 @@ static void walkDoc(xmlDocPtr doc) {
int ret;
#ifdef LIBXML_PATTERN_ENABLED
- xmlNodePtr root;
- const xmlChar *namespaces[22];
- int i;
- xmlNsPtr ns;
-
- root = xmlDocGetRootElement(doc);
- if (root == NULL ) {
- xmlGenericError(xmlGenericErrorContext,
- "Document does not have a root element");
- progresult = XMLLINT_ERR_UNCLASS;
- return;
- }
- for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
- namespaces[i++] = ns->href;
- namespaces[i++] = ns->prefix;
- }
- namespaces[i++] = NULL;
- namespaces[i] = NULL;
-
if (pattern != NULL) {
- patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
- 0, &namespaces[0]);
+ xmlNodePtr root;
+ const xmlChar *namespaces[22];
+ int i;
+ xmlNsPtr ns;
+
+ root = xmlDocGetRootElement(doc);
+ if (root == NULL ) {
+ fprintf(ERR_STREAM,
+ "Document does not have a root element");
+ progresult = XMLLINT_ERR_UNCLASS;
+ return;
+ }
+ for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
+ namespaces[i++] = ns->href;
+ namespaces[i++] = ns->prefix;
+ }
+ namespaces[i++] = NULL;
+ namespaces[i] = NULL;
+
+ ret = xmlPatternCompileSafe((const xmlChar *) pattern, doc->dict,
+ 0, &namespaces[0], &patternc);
if (patternc == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Pattern %s failed to compile\n", pattern);
- progresult = XMLLINT_ERR_SCHEMAPAT;
- pattern = NULL;
- }
- }
- if (patternc != NULL) {
- patstream = xmlPatternGetStreamCtxt(patternc);
- if (patstream != NULL) {
- ret = xmlStreamPush(patstream, NULL, NULL);
- if (ret < 0) {
- fprintf(stderr, "xmlStreamPush() failure\n");
- xmlFreeStreamCtxt(patstream);
- patstream = NULL;
+ if (ret < 0) {
+ progresult = XMLLINT_ERR_MEM;
+ } else {
+ fprintf(ERR_STREAM,
+ "Pattern %s failed to compile\n", pattern);
+ progresult = XMLLINT_ERR_SCHEMAPAT;
}
+ goto error;
}
+
+ patstream = xmlPatternGetStreamCtxt(patternc);
+ if (patstream == NULL) {
+ progresult = XMLLINT_ERR_MEM;
+ goto error;
+ }
+
+ ret = xmlStreamPush(patstream, NULL, NULL);
+ if (ret < 0) {
+ fprintf(ERR_STREAM, "xmlStreamPush() failure\n");
+ progresult = XMLLINT_ERR_MEM;
+ goto error;
+ }
}
#endif /* LIBXML_PATTERN_ENABLED */
reader = xmlReaderWalker(doc);
@@ -1991,14 +1990,20 @@ static void walkDoc(xmlDocPtr doc) {
}
xmlFreeTextReader(reader);
if (ret != 0) {
- fprintf(stderr, "failed to walk through the doc\n");
+ fprintf(ERR_STREAM, "failed to walk through the doc\n");
progresult = XMLLINT_ERR_UNCLASS;
}
} else {
- fprintf(stderr, "Failed to crate a reader from the document\n");
+ fprintf(ERR_STREAM, "Failed to crate a reader from the document\n");
progresult = XMLLINT_ERR_UNCLASS;
}
+
#ifdef LIBXML_PATTERN_ENABLED
+error:
+ if (patternc != NULL) {
+ xmlFreePattern(patternc);
+ patternc = NULL;
+ }
if (patstream != NULL) {
xmlFreeStreamCtxt(patstream);
patstream = NULL;
@@ -2017,21 +2022,21 @@ static void walkDoc(xmlDocPtr doc) {
static void doXPathDump(xmlXPathObjectPtr cur) {
switch(cur->type) {
case XPATH_NODESET: {
- int i;
- xmlNodePtr node;
#ifdef LIBXML_OUTPUT_ENABLED
xmlOutputBufferPtr buf;
+ xmlNodePtr node;
+ int i;
if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
progresult = XMLLINT_ERR_XPATH_EMPTY;
if (!quiet) {
- fprintf(stderr, "XPath set is empty\n");
+ fprintf(ERR_STREAM, "XPath set is empty\n");
}
break;
}
buf = xmlOutputBufferCreateFile(stdout, NULL);
if (buf == NULL) {
- fprintf(stderr, "Out of memory for XPath\n");
+ fprintf(ERR_STREAM, "Out of memory for XPath\n");
progresult = XMLLINT_ERR_MEM;
return;
}
@@ -2070,11 +2075,11 @@ static void doXPathDump(xmlXPathObjectPtr cur) {
printf("%s\n", (const char *) cur->stringval);
break;
case XPATH_UNDEFINED:
- fprintf(stderr, "XPath Object is uninitialized\n");
+ fprintf(ERR_STREAM, "XPath Object is uninitialized\n");
progresult = XMLLINT_ERR_XPATH;
break;
default:
- fprintf(stderr, "XPath object of unexpected type\n");
+ fprintf(ERR_STREAM, "XPath object of unexpected type\n");
progresult = XMLLINT_ERR_XPATH;
break;
}
@@ -2086,7 +2091,7 @@ static void doXPathQuery(xmlDocPtr doc, const char *query) {
ctxt = xmlXPathNewContext(doc);
if (ctxt == NULL) {
- fprintf(stderr, "Out of memory for XPath\n");
+ fprintf(ERR_STREAM, "Out of memory for XPath\n");
progresult = XMLLINT_ERR_MEM;
return;
}
@@ -2095,7 +2100,7 @@ static void doXPathQuery(xmlDocPtr doc, const char *query) {
xmlXPathFreeContext(ctxt);
if (res == NULL) {
- fprintf(stderr, "XPath evaluation failure\n");
+ fprintf(ERR_STREAM, "XPath evaluation failure\n");
progresult = XMLLINT_ERR_XPATH;
return;
}
@@ -2109,44 +2114,54 @@ static void doXPathQuery(xmlDocPtr doc, const char *query) {
* Tree Test processing *
* *
************************************************************************/
-static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
- xmlDocPtr doc = NULL;
-#ifdef LIBXML_TREE_ENABLED
- xmlDocPtr tmp;
-#endif /* LIBXML_TREE_ENABLED */
-
- if ((timing) && (!repeat))
- startTimer();
+static xmlDocPtr
+parseFile(const char *filename, xmlParserCtxtPtr rectxt) {
+ xmlParserCtxtPtr ctxt;
+ xmlDocPtr doc = NULL;
#ifdef LIBXML_TREE_ENABLED
- if (filename == NULL) {
- if (generate) {
- xmlNodePtr n;
+ if ((generate) && (filename == NULL)) {
+ xmlNodePtr n;
- doc = xmlNewDoc(BAD_CAST "1.0");
- n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
- xmlNodeSetContent(n, BAD_CAST "abc");
- xmlDocSetRootElement(doc, n);
- }
+ doc = xmlNewDoc(BAD_CAST "1.0");
+ if (doc == NULL) {
+ progresult = XMLLINT_ERR_MEM;
+ return(NULL);
+ }
+ n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
+ if (n == NULL) {
+ xmlFreeDoc(doc);
+ progresult = XMLLINT_ERR_MEM;
+ return(NULL);
+ }
+ if (xmlNodeSetContent(n, BAD_CAST "abc") < 0) {
+ xmlFreeNode(n);
+ xmlFreeDoc(doc);
+ progresult = XMLLINT_ERR_MEM;
+ return(NULL);
+ }
+ xmlDocSetRootElement(doc, n);
+
+ return(doc);
}
#endif /* LIBXML_TREE_ENABLED */
+
#ifdef LIBXML_HTML_ENABLED
#ifdef LIBXML_PUSH_ENABLED
- else if ((html) && (push)) {
+ if ((html) && (push)) {
FILE *f;
int res;
char chars[4096];
- htmlParserCtxtPtr ctxt;
if ((filename[0] == '-') && (filename[1] == 0)) {
f = stdin;
} else {
f = fopen(filename, "rb");
if (f == NULL) {
- fprintf(stderr, "Can't open %s\n", filename);
- progresult = XMLLINT_ERR_UNCLASS;
- return;
+ fprintf(ERR_STREAM, "Can't open %s\n", filename);
+ progresult = XMLLINT_ERR_RDFILE;
+ return(NULL);
}
}
@@ -2157,7 +2172,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
progresult = XMLLINT_ERR_MEM;
if (f != stdin)
fclose(f);
- return;
+ return(NULL);
}
htmlCtxtUseOptions(ctxt, options);
while ((res = fread(chars, 1, pushsize, f)) > 0) {
@@ -2168,23 +2183,26 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
htmlFreeParserCtxt(ctxt);
if (f != stdin)
fclose(f);
+
+ return(doc);
}
#endif /* LIBXML_PUSH_ENABLED */
+
#ifdef HAVE_MMAP
- else if ((html) && (memory)) {
+ if ((html) && (memory)) {
int fd;
struct stat info;
const char *base;
if (stat(filename, &info) < 0)
- return;
+ return(NULL);
if ((fd = open(filename, O_RDONLY)) < 0)
- return;
+ return(NULL);
base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
if (base == (void *) MAP_FAILED) {
close(fd);
- fprintf(stderr, "mmap failure for file %s\n", filename);
+ fprintf(ERR_STREAM, "mmap failure for file %s\n", filename);
progresult = XMLLINT_ERR_RDFILE;
- return;
+ return(NULL);
}
doc = htmlReadMemory((char *) base, info.st_size, filename,
@@ -2192,191 +2210,168 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
munmap((char *) base, info.st_size);
close(fd);
+
+ return(doc);
}
#endif
- else if (html) {
- doc = htmlReadFile(filename, NULL, options);
+
+ if (html) {
+ if (strcmp(filename, "-") == 0)
+ doc = htmlReadFd(STDIN_FILENO, "-", NULL, options);
+ else
+ doc = htmlReadFile(filename, NULL, options);
+
+ return(doc);
}
#endif /* LIBXML_HTML_ENABLED */
- else {
-#ifdef LIBXML_PUSH_ENABLED
- /*
- * build an XML tree from a string;
- */
- if (push) {
- FILE *f;
- int ret;
- int res, size = 1024;
- char chars[1024];
- xmlParserCtxtPtr ctxt;
- /* '-' Usually means stdin - */
- if ((filename[0] == '-') && (filename[1] == 0)) {
- f = stdin;
- } else {
- f = fopen(filename, "rb");
- if (f == NULL) {
- fprintf(stderr, "Can't open %s\n", filename);
- progresult = XMLLINT_ERR_UNCLASS;
- return;
- }
- }
+#ifdef LIBXML_PUSH_ENABLED
+ if (push) {
+ FILE *f;
+ int res;
+ char chars[4096];
- res = fread(chars, 1, 4, f);
- ctxt = xmlCreatePushParserCtxt(NULL, NULL,
- chars, res, filename);
- if (ctxt == NULL) {
- progresult = XMLLINT_ERR_MEM;
- if (f != stdin)
- fclose(f);
- return;
- }
- xmlCtxtUseOptions(ctxt, options);
- if (maxAmpl > 0)
- xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
- while ((res = fread(chars, 1, size, f)) > 0) {
- xmlParseChunk(ctxt, chars, res, 0);
- }
- xmlParseChunk(ctxt, chars, 0, 1);
- doc = ctxt->myDoc;
- ret = ctxt->wellFormed;
- xmlFreeParserCtxt(ctxt);
- if ((!ret) && (!recovery)) {
- xmlFreeDoc(doc);
- doc = NULL;
+ if ((filename[0] == '-') && (filename[1] == 0)) {
+ f = stdin;
+ } else {
+ f = fopen(filename, "rb");
+ if (f == NULL) {
+ fprintf(ERR_STREAM, "Can't open %s\n", filename);
+ progresult = XMLLINT_ERR_RDFILE;
+ return(NULL);
}
+ }
+
+ res = fread(chars, 1, 4, f);
+ ctxt = xmlCreatePushParserCtxt(NULL, NULL,
+ chars, res, filename);
+ if (ctxt == NULL) {
+ progresult = XMLLINT_ERR_MEM;
if (f != stdin)
fclose(f);
- } else
-#endif /* LIBXML_PUSH_ENABLED */
- if (testIO) {
- if ((filename[0] == '-') && (filename[1] == 0)) {
- doc = xmlReadFd(0, NULL, NULL, options);
- } else {
- FILE *f;
+ return(NULL);
+ }
+ xmlCtxtUseOptions(ctxt, options);
- f = fopen(filename, "rb");
- if (f != NULL) {
- if (rectxt == NULL)
- doc = xmlReadIO(myRead, myClose, f, filename, NULL,
- options);
- else
- doc = xmlCtxtReadIO(rectxt, myRead, myClose, f,
- filename, NULL, options);
- } else
- doc = NULL;
- }
- } else if (htmlout) {
- xmlParserCtxtPtr ctxt;
-
- if (rectxt == NULL) {
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- progresult = XMLLINT_ERR_MEM;
- return;
- }
- if (maxAmpl > 0)
- xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
- } else {
- ctxt = rectxt;
- }
+ if (maxAmpl > 0)
+ xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
+ if (htmlout) {
ctxt->sax->error = xmlHTMLError;
ctxt->sax->warning = xmlHTMLWarning;
ctxt->vctxt.error = xmlHTMLValidityError;
ctxt->vctxt.warning = xmlHTMLValidityWarning;
+ }
- doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+ while ((res = fread(chars, 1, pushsize, f)) > 0) {
+ xmlParseChunk(ctxt, chars, res, 0);
+ }
+ xmlParseChunk(ctxt, chars, 0, 1);
- if (rectxt == NULL)
- xmlFreeParserCtxt(ctxt);
-#ifdef HAVE_MMAP
- } else if (memory) {
- int fd;
- struct stat info;
- const char *base;
- if (stat(filename, &info) < 0)
- return;
- if ((fd = open(filename, O_RDONLY)) < 0)
- return;
- base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
- if (base == (void *) MAP_FAILED) {
- close(fd);
- fprintf(stderr, "mmap failure for file %s\n", filename);
- progresult = XMLLINT_ERR_RDFILE;
- return;
- }
+ doc = ctxt->myDoc;
+ if (f != stdin)
+ fclose(f);
+ } else
+#endif /* LIBXML_PUSH_ENABLED */
+ {
+ if (rectxt == NULL) {
+ ctxt = xmlNewParserCtxt();
+ if (ctxt == NULL) {
+ progresult = XMLLINT_ERR_MEM;
+ return(NULL);
+ }
+ } else {
+ ctxt = rectxt;
+ }
- if (rectxt == NULL) {
- xmlParserCtxtPtr ctxt;
+ if (maxAmpl > 0)
+ xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- fprintf(stderr, "out of memory\n");
- progresult = XMLLINT_ERR_MEM;
- return;
- }
- if (maxAmpl > 0)
- xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
- doc = xmlCtxtReadMemory(ctxt, base, info.st_size,
- filename, NULL, options);
- xmlFreeParserCtxt(ctxt);
- } else {
- doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
- filename, NULL, options);
- }
+ if (htmlout) {
+ ctxt->sax->error = xmlHTMLError;
+ ctxt->sax->warning = xmlHTMLWarning;
+ ctxt->vctxt.error = xmlHTMLValidityError;
+ ctxt->vctxt.warning = xmlHTMLValidityWarning;
+ }
- munmap((char *) base, info.st_size);
- close(fd);
-#endif
-#ifdef LIBXML_VALID_ENABLED
- } else if (valid) {
- xmlParserCtxtPtr ctxt = NULL;
-
- if (rectxt == NULL) {
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- progresult = XMLLINT_ERR_MEM;
- return;
- }
+ if (testIO) {
+ FILE *f;
+
+ if ((filename[0] == '-') && (filename[1] == 0)) {
+ f = stdin;
} else {
- ctxt = rectxt;
+ f = fopen(filename, "rb");
+ if (f == NULL) {
+ fprintf(ERR_STREAM, "Can't open %s\n", filename);
+ progresult = XMLLINT_ERR_RDFILE;
+ goto error;
+ }
}
- if (maxAmpl > 0)
- xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
- doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
-
- if (ctxt->valid == 0)
+ doc = xmlCtxtReadIO(ctxt, myRead, myClose, f, filename, NULL,
+ options);
+#ifdef HAVE_MMAP
+ } else if (memory) {
+ int fd;
+ struct stat info;
+ const char *base;
+
+ if (stat(filename, &info) < 0)
+ goto error;
+ if ((fd = open(filename, O_RDONLY)) < 0)
+ goto error;
+ base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
+ if (base == (void *) MAP_FAILED) {
+ close(fd);
+ fprintf(ERR_STREAM, "mmap failure for file %s\n", filename);
progresult = XMLLINT_ERR_RDFILE;
- if (rectxt == NULL)
- xmlFreeParserCtxt(ctxt);
-#endif /* LIBXML_VALID_ENABLED */
- } else {
- if (rectxt != NULL) {
- doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
- } else {
- xmlParserCtxtPtr ctxt;
+ goto error;
+ }
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- fprintf(stderr, "out of memory\n");
- progresult = XMLLINT_ERR_MEM;
- return;
- }
- if (maxAmpl > 0)
- xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
+ doc = xmlCtxtReadMemory(ctxt, base, info.st_size, filename, NULL,
+ options);
+
+ munmap((char *) base, info.st_size);
+ close(fd);
+#endif
+ } else {
+ if (strcmp(filename, "-") == 0)
+ doc = xmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL, options);
+ else
doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
- xmlFreeParserCtxt(ctxt);
- }
- }
+ }
}
- /*
- * If we don't have a document we might as well give up. Do we
- * want an error message here? */
if (doc == NULL) {
- progresult = XMLLINT_ERR_UNCLASS;
+ if (ctxt->errNo == XML_ERR_NO_MEMORY)
+ progresult = XMLLINT_ERR_MEM;
+ else
+ progresult = XMLLINT_ERR_RDFILE;
+ } else {
+#ifdef LIBXML_VALID_ENABLED
+ if ((options & XML_PARSE_DTDVALID) && (ctxt->valid == 0))
+ progresult = XMLLINT_ERR_VALID;
+#endif /* LIBXML_VALID_ENABLED */
+ }
+
+error:
+ if (ctxt != rectxt)
+ xmlFreeParserCtxt(ctxt);
+
+ return(doc);
+}
+
+static void
+parseAndPrintFile(const char *filename, xmlParserCtxtPtr rectxt) {
+ xmlDocPtr doc;
+
+ if ((timing) && (!repeat))
+ startTimer();
+
+ doc = parseFile(filename, rectxt);
+ if (doc == NULL) {
+ if (progresult == XMLLINT_RETURN_OK)
+ progresult = XMLLINT_ERR_UNCLASS;
return;
}
@@ -2384,17 +2379,13 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
endTimer("Parsing");
}
- /*
- * Remove DOCTYPE nodes
- */
if (dropdtd) {
xmlDtdPtr dtd;
dtd = xmlGetIntSubset(doc);
if (dtd != NULL) {
xmlUnlinkNode((xmlNodePtr)dtd);
- doc->intSubset = NULL;
- xmlFreeDtd(dtd);
+ doc->intSubset = dtd;
}
}
@@ -2434,6 +2425,8 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
* test intermediate copy if needed.
*/
if (copy) {
+ xmlDocPtr tmp;
+
tmp = doc;
if (timing) {
startTimer();
@@ -2458,25 +2451,32 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
#endif /* LIBXML_TREE_ENABLED */
#ifdef LIBXML_VALID_ENABLED
- if ((insert) && (!html)) {
+ if ((insert)
+#ifdef LIBXML_HTML_ENABLED
+ && (!html)
+#endif
+ ) {
const xmlChar* list[256];
int nb, i;
xmlNodePtr node;
if (doc->children != NULL) {
node = doc->children;
- while ((node != NULL) && (node->last == NULL)) node = node->next;
+ while ((node != NULL) &&
+ ((node->type != XML_ELEMENT_NODE) ||
+ (node->last == NULL)))
+ node = node->next;
if (node != NULL) {
nb = xmlValidGetValidElements(node->last, NULL, list, 256);
if (nb < 0) {
- fprintf(stderr, "could not get valid list of elements\n");
+ fprintf(ERR_STREAM, "could not get valid list of elements\n");
} else if (nb == 0) {
- fprintf(stderr, "No element can be inserted under root\n");
+ fprintf(ERR_STREAM, "No element can be inserted under root\n");
} else {
- fprintf(stderr, "%d element types can be inserted under root:\n",
+ fprintf(ERR_STREAM, "%d element types can be inserted under root:\n",
nb);
for (i = 0;i < nb;i++) {
- fprintf(stderr, "%s\n", (char *) list[i]);
+ fprintf(ERR_STREAM, "%s\n", (char *) list[i]);
}
}
}
@@ -2490,7 +2490,8 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
#endif /* LIBXML_READER_ENABLED */
#ifdef LIBXML_OUTPUT_ENABLED
if (noout == 0) {
- int ret;
+ if (compress)
+ xmlSetDocCompressMode(doc, 9);
/*
* print it.
@@ -2531,7 +2532,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
if (output != NULL)
fclose(out);
} else {
- fprintf(stderr, "failed to open %s\n", output);
+ fprintf(ERR_STREAM, "failed to open %s\n", output);
progresult = XMLLINT_ERR_OUT;
}
}
@@ -2548,11 +2549,11 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
if (size >= 0) {
if (write(1, result, size) == -1) {
- fprintf(stderr, "Can't write data\n");
+ fprintf(ERR_STREAM, "Can't write data\n");
}
xmlFree(result);
} else {
- fprintf(stderr, "Failed to canonicalize\n");
+ fprintf(ERR_STREAM, "Failed to canonicalize\n");
progresult = XMLLINT_ERR_OUT;
}
} else if (canonical_11) {
@@ -2562,11 +2563,11 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
if (size >= 0) {
if (write(1, result, size) == -1) {
- fprintf(stderr, "Can't write data\n");
+ fprintf(ERR_STREAM, "Can't write data\n");
}
xmlFree(result);
} else {
- fprintf(stderr, "Failed to canonicalize\n");
+ fprintf(ERR_STREAM, "Failed to canonicalize\n");
progresult = XMLLINT_ERR_OUT;
}
} else
@@ -2577,11 +2578,11 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
if (size >= 0) {
if (write(1, result, size) == -1) {
- fprintf(stderr, "Can't write data\n");
+ fprintf(ERR_STREAM, "Can't write data\n");
}
xmlFree(result);
} else {
- fprintf(stderr, "Failed to canonicalize\n");
+ fprintf(ERR_STREAM, "Failed to canonicalize\n");
progresult = XMLLINT_ERR_OUT;
}
} else
@@ -2604,11 +2605,11 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
xmlDocDumpMemory(doc, &result, &len);
}
if (result == NULL) {
- fprintf(stderr, "Failed to save\n");
+ fprintf(ERR_STREAM, "Failed to save\n");
progresult = XMLLINT_ERR_OUT;
} else {
if (write(1, result, len) == -1) {
- fprintf(stderr, "Can't write data\n");
+ fprintf(ERR_STREAM, "Can't write data\n");
}
xmlFree(result);
}
@@ -2617,46 +2618,6 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
#endif /* HAVE_MMAP */
if (compress) {
xmlSaveFile(output ? output : "-", doc);
- } else if (oldout) {
- if (encoding != NULL) {
- if (format == 1) {
- ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
- encoding, 1);
- }
- else {
- ret = xmlSaveFileEnc(output ? output : "-", doc,
- encoding);
- }
- if (ret < 0) {
- fprintf(stderr, "failed save to %s\n",
- output ? output : "-");
- progresult = XMLLINT_ERR_OUT;
- }
- } else if (format == 1) {
- ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
- if (ret < 0) {
- fprintf(stderr, "failed save to %s\n",
- output ? output : "-");
- progresult = XMLLINT_ERR_OUT;
- }
- } else {
- FILE *out;
- if (output == NULL)
- out = stdout;
- else {
- out = fopen(output,"wb");
- }
- if (out != NULL) {
- if (xmlDocDump(out, doc) < 0)
- progresult = XMLLINT_ERR_OUT;
-
- if (output != NULL)
- fclose(out);
- } else {
- fprintf(stderr, "failed to open %s\n", output);
- progresult = XMLLINT_ERR_OUT;
- }
- }
} else {
xmlSaveCtxtPtr ctxt;
int saveOpts = 0;
@@ -2666,7 +2627,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
else if (format == 2)
saveOpts |= XML_SAVE_WSNONSIG;
-#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
+#if defined(LIBXML_HTML_ENABLED)
if (xmlout)
saveOpts |= XML_SAVE_AS_XML;
#endif
@@ -2678,7 +2639,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
if (ctxt != NULL) {
if (xmlSaveDoc(ctxt, doc) < 0) {
- fprintf(stderr, "failed save to %s\n",
+ fprintf(ERR_STREAM, "failed save to %s\n",
output ? output : "-");
progresult = XMLLINT_ERR_OUT;
}
@@ -2704,7 +2665,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
if (output != NULL)
fclose(out);
} else {
- fprintf(stderr, "failed to open %s\n", output);
+ fprintf(ERR_STREAM, "failed to open %s\n", output);
progresult = XMLLINT_ERR_OUT;
}
}
@@ -2731,35 +2692,33 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
}
if (dtd == NULL) {
if (dtdvalid != NULL)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Could not parse DTD %s\n", dtdvalid);
else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Could not parse DTD %s\n", dtdvalidfpi);
progresult = XMLLINT_ERR_DTD;
} else {
xmlValidCtxtPtr cvp;
if ((cvp = xmlNewValidCtxt()) == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Couldn't allocate validation context\n");
progresult = XMLLINT_ERR_MEM;
xmlFreeDtd(dtd);
return;
}
- cvp->error = xmlGenericError;
- cvp->warning = xmlGenericError;
if ((timing) && (!repeat)) {
startTimer();
}
if (!xmlValidateDtd(cvp, doc, dtd)) {
if (dtdvalid != NULL)
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Document %s does not validate against %s\n",
filename, dtdvalid);
else
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Document %s does not validate against %s\n",
filename, dtdvalidfpi);
progresult = XMLLINT_ERR_VALID;
@@ -2774,7 +2733,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
xmlValidCtxtPtr cvp;
if ((cvp = xmlNewValidCtxt()) == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Couldn't allocate validation context\n");
progresult = XMLLINT_ERR_MEM;
xmlFreeDoc(doc);
@@ -2784,10 +2743,8 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
if ((timing) && (!repeat)) {
startTimer();
}
- cvp->error = xmlGenericError;
- cvp->warning = xmlGenericError;
if (!xmlValidateDocument(cvp, doc)) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Document %s does not validate\n", filename);
progresult = XMLLINT_ERR_VALID;
}
@@ -2819,20 +2776,16 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
xmlFreeDoc(doc);
return;
}
-#if 0
- xmlSchematronSetValidErrors(ctxt, xmlGenericError, xmlGenericError,
- NULL);
-#endif
ret = xmlSchematronValidateDoc(ctxt, doc);
if (ret == 0) {
if (!quiet) {
- fprintf(stderr, "%s validates\n", filename);
+ fprintf(ERR_STREAM, "%s validates\n", filename);
}
} else if (ret > 0) {
- fprintf(stderr, "%s fails to validate\n", filename);
+ fprintf(ERR_STREAM, "%s fails to validate\n", filename);
progresult = XMLLINT_ERR_VALID;
} else {
- fprintf(stderr, "%s validation generated an internal error\n",
+ fprintf(ERR_STREAM, "%s validation generated an internal error\n",
filename);
progresult = XMLLINT_ERR_VALID;
}
@@ -2857,17 +2810,16 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
xmlFreeDoc(doc);
return;
}
- xmlRelaxNGSetValidErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
ret = xmlRelaxNGValidateDoc(ctxt, doc);
if (ret == 0) {
if (!quiet) {
- fprintf(stderr, "%s validates\n", filename);
+ fprintf(ERR_STREAM, "%s validates\n", filename);
}
} else if (ret > 0) {
- fprintf(stderr, "%s fails to validate\n", filename);
+ fprintf(ERR_STREAM, "%s fails to validate\n", filename);
progresult = XMLLINT_ERR_VALID;
} else {
- fprintf(stderr, "%s validation generated an internal error\n",
+ fprintf(ERR_STREAM, "%s validation generated an internal error\n",
filename);
progresult = XMLLINT_ERR_VALID;
}
@@ -2889,17 +2841,16 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
xmlFreeDoc(doc);
return;
}
- xmlSchemaSetValidErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
ret = xmlSchemaValidateDoc(ctxt, doc);
if (ret == 0) {
if (!quiet) {
- fprintf(stderr, "%s validates\n", filename);
+ fprintf(ERR_STREAM, "%s validates\n", filename);
}
} else if (ret > 0) {
- fprintf(stderr, "%s fails to validate\n", filename);
+ fprintf(ERR_STREAM, "%s fails to validate\n", filename);
progresult = XMLLINT_ERR_VALID;
} else {
- fprintf(stderr, "%s validation generated an internal error\n",
+ fprintf(ERR_STREAM, "%s validation generated an internal error\n",
filename);
progresult = XMLLINT_ERR_VALID;
}
@@ -2911,10 +2862,12 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
#endif
#ifdef LIBXML_DEBUG_ENABLED
-#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
- if ((debugent) && (!html))
- xmlDebugDumpEntities(stderr, doc);
+ if ((debugent)
+#if defined(LIBXML_HTML_ENABLED)
+ && (!html)
#endif
+ )
+ xmlDebugDumpEntities(ERR_STREAM, doc);
#endif
/*
@@ -2936,42 +2889,40 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
************************************************************************/
static void showVersion(const char *name) {
- fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
- fprintf(stderr, " compiled with: ");
- if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
- if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
- if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
- if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
- if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
- if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
- if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
- if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
- if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
- if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
- if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
- if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
- if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
- if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
- if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
- if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
- if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
- if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
- if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
- if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU ");
- if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
- if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
- if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
- if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
- if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
- if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
- if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
- if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
- if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
- if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
- if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
- if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
- if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
- fprintf(stderr, "\n");
+ fprintf(ERR_STREAM, "%s: using libxml version %s\n", name, xmlParserVersion);
+ fprintf(ERR_STREAM, " compiled with: ");
+ if (xmlHasFeature(XML_WITH_THREAD)) fprintf(ERR_STREAM, "Threads ");
+ if (xmlHasFeature(XML_WITH_TREE)) fprintf(ERR_STREAM, "Tree ");
+ if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(ERR_STREAM, "Output ");
+ if (xmlHasFeature(XML_WITH_PUSH)) fprintf(ERR_STREAM, "Push ");
+ if (xmlHasFeature(XML_WITH_READER)) fprintf(ERR_STREAM, "Reader ");
+ if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(ERR_STREAM, "Patterns ");
+ if (xmlHasFeature(XML_WITH_WRITER)) fprintf(ERR_STREAM, "Writer ");
+ if (xmlHasFeature(XML_WITH_SAX1)) fprintf(ERR_STREAM, "SAXv1 ");
+ if (xmlHasFeature(XML_WITH_FTP)) fprintf(ERR_STREAM, "FTP ");
+ if (xmlHasFeature(XML_WITH_HTTP)) fprintf(ERR_STREAM, "HTTP ");
+ if (xmlHasFeature(XML_WITH_VALID)) fprintf(ERR_STREAM, "DTDValid ");
+ if (xmlHasFeature(XML_WITH_HTML)) fprintf(ERR_STREAM, "HTML ");
+ if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(ERR_STREAM, "Legacy ");
+ if (xmlHasFeature(XML_WITH_C14N)) fprintf(ERR_STREAM, "C14N ");
+ if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(ERR_STREAM, "Catalog ");
+ if (xmlHasFeature(XML_WITH_XPATH)) fprintf(ERR_STREAM, "XPath ");
+ if (xmlHasFeature(XML_WITH_XPTR)) fprintf(ERR_STREAM, "XPointer ");
+ if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(ERR_STREAM, "XInclude ");
+ if (xmlHasFeature(XML_WITH_ICONV)) fprintf(ERR_STREAM, "Iconv ");
+ if (xmlHasFeature(XML_WITH_ICU)) fprintf(ERR_STREAM, "ICU ");
+ if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(ERR_STREAM, "ISO8859X ");
+ if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(ERR_STREAM, "Unicode ");
+ if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(ERR_STREAM, "Regexps ");
+ if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(ERR_STREAM, "Automata ");
+ if (xmlHasFeature(XML_WITH_EXPR)) fprintf(ERR_STREAM, "Expr ");
+ if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(ERR_STREAM, "Schemas ");
+ if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(ERR_STREAM, "Schematron ");
+ if (xmlHasFeature(XML_WITH_MODULES)) fprintf(ERR_STREAM, "Modules ");
+ if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(ERR_STREAM, "Debug ");
+ if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(ERR_STREAM, "Zlib ");
+ if (xmlHasFeature(XML_WITH_LZMA)) fprintf(ERR_STREAM, "Lzma ");
+ fprintf(ERR_STREAM, "\n");
}
static void usage(FILE *f, const char *name) {
@@ -3010,17 +2961,12 @@ static void usage(FILE *f, const char *name) {
fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
+ fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
#endif /* LIBXML_VALID_ENABLED */
fprintf(f, "\t--quiet : be quiet when succeeded\n");
fprintf(f, "\t--timing : print some timings\n");
- fprintf(f, "\t--output file or -o file: save to a given file\n");
fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
- fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
-#ifdef LIBXML_OUTPUT_ENABLED
-#ifdef LIBXML_ZLIB_ENABLED
- fprintf(f, "\t--compress : turn on gzip compression of output\n");
-#endif
-#endif /* LIBXML_OUTPUT_ENABLED */
+ fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
#ifdef LIBXML_HTML_ENABLED
fprintf(f, "\t--html : use the HTML parser\n");
fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
@@ -3038,13 +2984,16 @@ static void usage(FILE *f, const char *name) {
fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
#ifdef LIBXML_OUTPUT_ENABLED
+ fprintf(f, "\t--output file or -o file: save to a given file\n");
fprintf(f, "\t--format : reformat/reindent the output\n");
fprintf(f, "\t--encode encoding : output in the given encoding\n");
- fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
fprintf(f, "\t 0 Do not pretty print\n");
fprintf(f, "\t 1 Format the XML content, as --format\n");
fprintf(f, "\t 2 Add whitespace inside tags, preserving content\n");
+#ifdef LIBXML_ZLIB_ENABLED
+ fprintf(f, "\t--compress : turn on gzip compression of output\n");
+#endif
#endif /* LIBXML_OUTPUT_ENABLED */
fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
@@ -3074,7 +3023,6 @@ static void usage(FILE *f, const char *name) {
fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
#endif
#endif /* LIBXML_READER_ENABLED */
- fprintf(f, "\t--chkregister : verify the node registration code\n");
#ifdef LIBXML_SCHEMAS_ENABLED
fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
@@ -3095,25 +3043,6 @@ static void usage(FILE *f, const char *name) {
fprintf(f, "\nLibxml project home page: https://gitlab.gnome.org/GNOME/libxml2\n");
}
-static void registerNode(xmlNodePtr node)
-{
- node->_private = malloc(sizeof(long));
- if (node->_private == NULL) {
- fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
- exit(XMLLINT_ERR_MEM);
- }
- *(long*)node->_private = (long) 0x81726354;
- nbregister++;
-}
-
-static void deregisterNode(xmlNodePtr node)
-{
- assert(node->_private != NULL);
- assert(*(long*)node->_private == (long) 0x81726354);
- free(node->_private);
- nbregister--;
-}
-
static unsigned long
parseInteger(const char *ctxt, const char *str,
unsigned long min, unsigned long max) {
@@ -3123,43 +3052,175 @@ parseInteger(const char *ctxt, const char *str,
errno = 0;
val = strtoul(str, &strEnd, 10);
if (errno == EINVAL || *strEnd != 0) {
- fprintf(stderr, "%s: invalid integer: %s\n", ctxt, str);
+ fprintf(ERR_STREAM, "%s: invalid integer: %s\n", ctxt, str);
exit(XMLLINT_ERR_UNCLASS);
}
if (errno != 0 || val < min || val > max) {
- fprintf(stderr, "%s: integer out of range: %s\n", ctxt, str);
+ fprintf(ERR_STREAM, "%s: integer out of range: %s\n", ctxt, str);
exit(XMLLINT_ERR_UNCLASS);
}
return(val);
}
-int
-main(int argc, char **argv) {
+static int
+skipArgs(const char *arg) {
+ if ((!strcmp(arg, "-path")) ||
+ (!strcmp(arg, "--path")) ||
+ (!strcmp(arg, "-maxmem")) ||
+ (!strcmp(arg, "--maxmem")) ||
+#ifdef LIBXML_OUTPUT_ENABLED
+ (!strcmp(arg, "-o")) ||
+ (!strcmp(arg, "-output")) ||
+ (!strcmp(arg, "--output")) ||
+ (!strcmp(arg, "-encode")) ||
+ (!strcmp(arg, "--encode")) ||
+ (!strcmp(arg, "-pretty")) ||
+ (!strcmp(arg, "--pretty")) ||
+#endif
+#ifdef LIBXML_VALID_ENABLED
+ (!strcmp(arg, "-dtdvalid")) ||
+ (!strcmp(arg, "--dtdvalid")) ||
+ (!strcmp(arg, "-dtdvalidfpi")) ||
+ (!strcmp(arg, "--dtdvalidfpi")) ||
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+ (!strcmp(arg, "-relaxng")) ||
+ (!strcmp(arg, "--relaxng")) ||
+ (!strcmp(arg, "-schema")) ||
+ (!strcmp(arg, "--schema")) ||
+#endif
+#ifdef LIBXML_SCHEMATRON_ENABLED
+ (!strcmp(arg, "-schematron")) ||
+ (!strcmp(arg, "--schematron")) ||
+#endif
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
+ (!strcmp(arg, "-pattern")) ||
+ (!strcmp(arg, "--pattern")) ||
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+ (!strcmp(arg, "-xpath")) ||
+ (!strcmp(arg, "--xpath")) ||
+#endif
+ (!strcmp(arg, "-max-ampl")) ||
+ (!strcmp(arg, "--max-ampl"))
+ ) {
+ return(1);
+ }
+
+ return(0);
+}
+
+static int
+xmllintMain(int argc, const char **argv) {
int i, acount;
int files = 0;
int version = 0;
+ int nowrap = 0;
+ int sax = 0;
+#ifdef LIBXML_READER_ENABLED
+ int stream = 0;
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+ int catalogs = 0;
+ int nocatalogs = 0;
+#endif
+
+#ifdef XMLLINT_FUZZ
+#ifdef LIBXML_DEBUG_ENABLED
+ shell = 0;
+ debugent = 0;
+#endif
+ debug = 0;
+ maxmem = 0;
+#ifdef LIBXML_TREE_ENABLED
+ copy = 0;
+#endif /* LIBXML_TREE_ENABLED */
+ noout = 0;
+#ifdef LIBXML_OUTPUT_ENABLED
+ format = 0;
+ output = NULL;
+ compress = 0;
+#endif /* LIBXML_OUTPUT_ENABLED */
+#ifdef LIBXML_VALID_ENABLED
+ postvalid = 0;
+ dtdvalid = NULL;
+ dtdvalidfpi = NULL;
+ insert = 0;
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+ relaxng = NULL;
+ relaxngschemas = NULL;
+ schema = NULL;
+ wxschemas = NULL;
+#endif
+#ifdef LIBXML_SCHEMATRON_ENABLED
+ schematron = NULL;
+ wxschematron = NULL;
+#endif
+ repeat = 0;
+#if defined(LIBXML_HTML_ENABLED)
+ html = 0;
+ xmlout = 0;
+#endif
+ htmlout = 0;
+#ifdef LIBXML_PUSH_ENABLED
+ push = 0;
+ pushsize = 4096;
+#endif /* LIBXML_PUSH_ENABLED */
+#ifdef HAVE_MMAP
+ memory = 0;
+#endif
+ testIO = 0;
+ encoding = NULL;
+#ifdef LIBXML_XINCLUDE_ENABLED
+ xinclude = 0;
+#endif
+ progresult = XMLLINT_RETURN_OK;
+ quiet = 0;
+ timing = 0;
+ generate = 0;
+ dropdtd = 0;
+#ifdef LIBXML_C14N_ENABLED
+ canonical = 0;
+ canonical_11 = 0;
+ exc_canonical = 0;
+#endif
+#ifdef LIBXML_READER_ENABLED
+ walker = 0;
+#ifdef LIBXML_PATTERN_ENABLED
+ pattern = NULL;
+ patternc = NULL;
+ patstream = NULL;
+#endif
+#endif /* LIBXML_READER_ENABLED */
+#ifdef LIBXML_XPATH_ENABLED
+ xpathquery = NULL;
+#endif
+ options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
+ maxAmpl = 0;
+ defaultEntityLoader = NULL;
+#endif /* XMLLINT_FUZZ */
if (argc <= 1) {
- usage(stderr, argv[0]);
+ usage(ERR_STREAM, argv[0]);
return(XMLLINT_ERR_UNCLASS);
}
/* xmlMemSetup must be called before initializing the parser. */
for (i = 1; i < argc ; i++) {
- if (argv[i][0] != '-')
- continue;
-
if ((!strcmp(argv[i], "-maxmem")) ||
(!strcmp(argv[i], "--maxmem"))) {
i++;
if (i >= argc) {
- fprintf(stderr, "maxmem: missing integer value\n");
+ fprintf(ERR_STREAM, "maxmem: missing integer value\n");
return(XMLLINT_ERR_UNCLASS);
}
errno = 0;
maxmem = parseInteger("maxmem", argv[i], 0, INT_MAX);
- }
+ } else if (argv[i][0] == '-') {
+ i += skipArgs(argv[i]);
+ }
}
if (maxmem != 0)
xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, myStrdupFunc);
@@ -3187,17 +3248,15 @@ main(int argc, char **argv) {
#endif /* LIBXML_TREE_ENABLED */
if ((!strcmp(argv[i], "-recover")) ||
(!strcmp(argv[i], "--recover"))) {
- recovery++;
options |= XML_PARSE_RECOVER;
} else if ((!strcmp(argv[i], "-huge")) ||
(!strcmp(argv[i], "--huge"))) {
options |= XML_PARSE_HUGE;
} else if ((!strcmp(argv[i], "-noent")) ||
(!strcmp(argv[i], "--noent"))) {
- noent = 1;
+ options |= XML_PARSE_NOENT;
} else if ((!strcmp(argv[i], "-noenc")) ||
(!strcmp(argv[i], "--noenc"))) {
- noenc++;
options |= XML_PARSE_IGNORE_ENC;
} else if ((!strcmp(argv[i], "-nsclean")) ||
(!strcmp(argv[i], "--nsclean"))) {
@@ -3215,14 +3274,6 @@ main(int argc, char **argv) {
} else if ((!strcmp(argv[i], "-noout")) ||
(!strcmp(argv[i], "--noout")))
noout++;
-#ifdef LIBXML_OUTPUT_ENABLED
- else if ((!strcmp(argv[i], "-o")) ||
- (!strcmp(argv[i], "-output")) ||
- (!strcmp(argv[i], "--output"))) {
- i++;
- output = argv[i];
- }
-#endif /* LIBXML_OUTPUT_ENABLED */
else if ((!strcmp(argv[i], "-htmlout")) ||
(!strcmp(argv[i], "--htmlout")))
htmlout++;
@@ -3239,50 +3290,42 @@ main(int argc, char **argv) {
xmlout++;
} else if ((!strcmp(argv[i], "-nodefdtd")) ||
(!strcmp(argv[i], "--nodefdtd"))) {
- nodefdtd++;
options |= HTML_PARSE_NODEFDTD;
}
#endif /* LIBXML_HTML_ENABLED */
else if ((!strcmp(argv[i], "-loaddtd")) ||
(!strcmp(argv[i], "--loaddtd"))) {
- loaddtd++;
options |= XML_PARSE_DTDLOAD;
} else if ((!strcmp(argv[i], "-dtdattr")) ||
(!strcmp(argv[i], "--dtdattr"))) {
- loaddtd++;
- dtdattrs++;
options |= XML_PARSE_DTDATTR;
}
#ifdef LIBXML_VALID_ENABLED
else if ((!strcmp(argv[i], "-valid")) ||
(!strcmp(argv[i], "--valid"))) {
- valid++;
options |= XML_PARSE_DTDVALID;
} else if ((!strcmp(argv[i], "-postvalid")) ||
(!strcmp(argv[i], "--postvalid"))) {
postvalid++;
- loaddtd++;
options |= XML_PARSE_DTDLOAD;
} else if ((!strcmp(argv[i], "-dtdvalid")) ||
(!strcmp(argv[i], "--dtdvalid"))) {
i++;
dtdvalid = argv[i];
- loaddtd++;
options |= XML_PARSE_DTDLOAD;
} else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
(!strcmp(argv[i], "--dtdvalidfpi"))) {
i++;
dtdvalidfpi = argv[i];
- loaddtd++;
options |= XML_PARSE_DTDLOAD;
}
+ else if ((!strcmp(argv[i], "-insert")) ||
+ (!strcmp(argv[i], "--insert")))
+ insert++;
#endif /* LIBXML_VALID_ENABLED */
else if ((!strcmp(argv[i], "-dropdtd")) ||
(!strcmp(argv[i], "--dropdtd")))
dropdtd++;
- else if ((!strcmp(argv[i], "-insert")) ||
- (!strcmp(argv[i], "--insert")))
- insert++;
else if ((!strcmp(argv[i], "-quiet")) ||
(!strcmp(argv[i], "--quiet")))
quiet++;
@@ -3336,15 +3379,6 @@ main(int argc, char **argv) {
options |= XML_PARSE_NOBASEFIX;
}
#endif
-#ifdef LIBXML_OUTPUT_ENABLED
-#ifdef LIBXML_ZLIB_ENABLED
- else if ((!strcmp(argv[i], "-compress")) ||
- (!strcmp(argv[i], "--compress"))) {
- compress++;
- xmlSetCompressMode(9);
- }
-#endif
-#endif /* LIBXML_OUTPUT_ENABLED */
else if ((!strcmp(argv[i], "-nowarning")) ||
(!strcmp(argv[i], "--nowarning"))) {
options |= XML_PARSE_NOWARNING;
@@ -3387,37 +3421,48 @@ main(int argc, char **argv) {
nocatalogs++;
}
#endif
- else if ((!strcmp(argv[i], "-encode")) ||
- (!strcmp(argv[i], "--encode"))) {
- i++;
- encoding = argv[i];
- /*
- * OK it's for testing purposes
- */
- xmlAddEncodingAlias("UTF-8", "DVEnc");
- }
else if ((!strcmp(argv[i], "-noblanks")) ||
(!strcmp(argv[i], "--noblanks"))) {
- noblanks = 1;
+ options |= XML_PARSE_NOBLANKS;
}
else if ((!strcmp(argv[i], "-maxmem")) ||
(!strcmp(argv[i], "--maxmem"))) {
i++;
}
+#ifdef LIBXML_OUTPUT_ENABLED
+ else if ((!strcmp(argv[i], "-o")) ||
+ (!strcmp(argv[i], "-output")) ||
+ (!strcmp(argv[i], "--output"))) {
+ i++;
+ output = argv[i];
+ }
else if ((!strcmp(argv[i], "-format")) ||
(!strcmp(argv[i], "--format"))) {
-#ifdef LIBXML_OUTPUT_ENABLED
format = 1;
-#endif /* LIBXML_OUTPUT_ENABLED */
+ options |= XML_PARSE_NOBLANKS;
}
+ else if ((!strcmp(argv[i], "-encode")) ||
+ (!strcmp(argv[i], "--encode"))) {
+ i++;
+ encoding = argv[i];
+ /*
+ * OK it's for testing purposes
+ */
+ xmlAddEncodingAlias("UTF-8", "DVEnc");
+ }
else if ((!strcmp(argv[i], "-pretty")) ||
(!strcmp(argv[i], "--pretty"))) {
i++;
-#ifdef LIBXML_OUTPUT_ENABLED
if (argv[i] != NULL)
format = atoi(argv[i]);
-#endif /* LIBXML_OUTPUT_ENABLED */
}
+#ifdef LIBXML_ZLIB_ENABLED
+ else if ((!strcmp(argv[i], "-compress")) ||
+ (!strcmp(argv[i], "--compress"))) {
+ compress++;
+ }
+#endif
+#endif /* LIBXML_OUTPUT_ENABLED */
#ifdef LIBXML_READER_ENABLED
else if ((!strcmp(argv[i], "-stream")) ||
(!strcmp(argv[i], "--stream"))) {
@@ -3427,51 +3472,52 @@ main(int argc, char **argv) {
(!strcmp(argv[i], "--walker"))) {
walker++;
noout++;
+ }
#ifdef LIBXML_PATTERN_ENABLED
- } else if ((!strcmp(argv[i], "-pattern")) ||
+ else if ((!strcmp(argv[i], "-pattern")) ||
(!strcmp(argv[i], "--pattern"))) {
i++;
pattern = argv[i];
-#endif
}
+#endif
#endif /* LIBXML_READER_ENABLED */
#ifdef LIBXML_SAX1_ENABLED
else if ((!strcmp(argv[i], "-sax1")) ||
(!strcmp(argv[i], "--sax1"))) {
- sax1++;
options |= XML_PARSE_SAX1;
}
#endif /* LIBXML_SAX1_ENABLED */
else if ((!strcmp(argv[i], "-sax")) ||
(!strcmp(argv[i], "--sax"))) {
sax++;
- }
- else if ((!strcmp(argv[i], "-chkregister")) ||
- (!strcmp(argv[i], "--chkregister"))) {
- chkregister++;
+ }
#ifdef LIBXML_SCHEMAS_ENABLED
- } else if ((!strcmp(argv[i], "-relaxng")) ||
+ else if ((!strcmp(argv[i], "-relaxng")) ||
(!strcmp(argv[i], "--relaxng"))) {
i++;
relaxng = argv[i];
- noent = 1;
+ options |= XML_PARSE_NOENT;
} else if ((!strcmp(argv[i], "-schema")) ||
(!strcmp(argv[i], "--schema"))) {
i++;
schema = argv[i];
- noent = 1;
+ options |= XML_PARSE_NOENT;
+ }
#endif
#ifdef LIBXML_SCHEMATRON_ENABLED
- } else if ((!strcmp(argv[i], "-schematron")) ||
+ else if ((!strcmp(argv[i], "-schematron")) ||
(!strcmp(argv[i], "--schematron"))) {
i++;
schematron = argv[i];
- noent = 1;
+ options |= XML_PARSE_NOENT;
+ }
#endif
- } else if ((!strcmp(argv[i], "-nonet")) ||
+ else if ((!strcmp(argv[i], "-nonet")) ||
(!strcmp(argv[i], "--nonet"))) {
options |= XML_PARSE_NONET;
+#ifndef XMLLINT_FUZZ
xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
+#endif
} else if ((!strcmp(argv[i], "-nocompact")) ||
(!strcmp(argv[i], "--nocompact"))) {
options &= ~XML_PARSE_COMPACT;
@@ -3482,28 +3528,29 @@ main(int argc, char **argv) {
(!strcmp(argv[i], "--path"))) {
i++;
parsePath(BAD_CAST argv[i]);
+ }
#ifdef LIBXML_XPATH_ENABLED
- } else if ((!strcmp(argv[i], "-xpath")) ||
+ else if ((!strcmp(argv[i], "-xpath")) ||
(!strcmp(argv[i], "--xpath"))) {
i++;
noout++;
xpathquery = argv[i];
+ }
#endif
- } else if ((!strcmp(argv[i], "-oldxml10")) ||
+ else if ((!strcmp(argv[i], "-oldxml10")) ||
(!strcmp(argv[i], "--oldxml10"))) {
- oldxml10++;
options |= XML_PARSE_OLD10;
} else if ((!strcmp(argv[i], "-max-ampl")) ||
(!strcmp(argv[i], "--max-ampl"))) {
i++;
if (i >= argc) {
- fprintf(stderr, "max-ampl: missing integer value\n");
+ fprintf(ERR_STREAM, "max-ampl: missing integer value\n");
return(XMLLINT_ERR_UNCLASS);
}
maxAmpl = parseInteger("max-ampl", argv[i], 1, UINT_MAX);
} else {
- fprintf(stderr, "Unknown option %s\n", argv[i]);
- usage(stderr, argv[0]);
+ fprintf(ERR_STREAM, "Unknown option %s\n", argv[i]);
+ usage(ERR_STREAM, argv[0]);
return(XMLLINT_ERR_UNCLASS);
}
}
@@ -3517,17 +3564,12 @@ main(int argc, char **argv) {
if (catal != NULL) {
xmlLoadCatalogs(catal);
} else {
- fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
+ fprintf(ERR_STREAM, "Variable $SGML_CATALOG_FILES not set\n");
}
}
}
#endif
- if (chkregister) {
- xmlRegisterNodeDefault(registerNode);
- xmlDeregisterNodeDefault(deregisterNode);
- }
-
#ifdef LIBXML_OUTPUT_ENABLED
{
const char *indent = getenv("XMLLINT_INDENT");
@@ -3540,19 +3582,15 @@ main(int argc, char **argv) {
defaultEntityLoader = xmlGetExternalEntityLoader();
xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
- if (noent != 0)
- options |= XML_PARSE_NOENT;
- if ((noblanks != 0) || (format == 1))
- options |= XML_PARSE_NOBLANKS;
if ((htmlout) && (!nowrap)) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"\n");
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"%s output\n",
argv[0]);
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"%s output
\n",
argv[0]);
}
@@ -3575,13 +3613,9 @@ main(int argc, char **argv) {
progresult = XMLLINT_ERR_MEM;
goto error;
}
-#if 0
- xmlSchematronSetParserErrors(ctxt, xmlGenericError, xmlGenericError,
- NULL);
-#endif
wxschematron = xmlSchematronParse(ctxt);
if (wxschematron == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Schematron schema %s failed to compile\n", schematron);
progresult = XMLLINT_ERR_SCHEMACOMP;
schematron = NULL;
@@ -3610,11 +3644,9 @@ main(int argc, char **argv) {
progresult = XMLLINT_ERR_MEM;
goto error;
}
- xmlRelaxNGSetParserErrors(ctxt, xmlGenericError, xmlGenericError,
- NULL);
relaxngschemas = xmlRelaxNGParse(ctxt);
if (relaxngschemas == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Relax-NG schema %s failed to compile\n", relaxng);
progresult = XMLLINT_ERR_SCHEMACOMP;
relaxng = NULL;
@@ -3638,10 +3670,9 @@ main(int argc, char **argv) {
progresult = XMLLINT_ERR_MEM;
goto error;
}
- xmlSchemaSetParserErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
wxschemas = xmlSchemaParse(ctxt);
if (wxschemas == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"WXS schema %s failed to compile\n", schema);
progresult = XMLLINT_ERR_SCHEMACOMP;
schema = NULL;
@@ -3656,7 +3687,7 @@ main(int argc, char **argv) {
if ((pattern != NULL) && (walker == 0)) {
patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
if (patternc == NULL) {
- xmlGenericError(xmlGenericErrorContext,
+ fprintf(ERR_STREAM,
"Pattern %s failed to compile\n", pattern);
progresult = XMLLINT_ERR_SCHEMAPAT;
pattern = NULL;
@@ -3664,141 +3695,64 @@ main(int argc, char **argv) {
}
#endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */
for (i = 1; i < argc ; i++) {
- if ((!strcmp(argv[i], "-encode")) ||
- (!strcmp(argv[i], "--encode"))) {
- i++;
- continue;
- } else if ((!strcmp(argv[i], "-o")) ||
- (!strcmp(argv[i], "-output")) ||
- (!strcmp(argv[i], "--output"))) {
- i++;
- continue;
- }
-#ifdef LIBXML_VALID_ENABLED
- if ((!strcmp(argv[i], "-dtdvalid")) ||
- (!strcmp(argv[i], "--dtdvalid"))) {
- i++;
- continue;
- }
- if ((!strcmp(argv[i], "-path")) ||
- (!strcmp(argv[i], "--path"))) {
- i++;
- continue;
- }
- if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
- (!strcmp(argv[i], "--dtdvalidfpi"))) {
- i++;
- continue;
- }
-#endif /* LIBXML_VALID_ENABLED */
- if ((!strcmp(argv[i], "-relaxng")) ||
- (!strcmp(argv[i], "--relaxng"))) {
- i++;
- continue;
- }
- if ((!strcmp(argv[i], "-maxmem")) ||
- (!strcmp(argv[i], "--maxmem"))) {
- i++;
- continue;
- }
- if ((!strcmp(argv[i], "-pretty")) ||
- (!strcmp(argv[i], "--pretty"))) {
- i++;
- continue;
- }
- if ((!strcmp(argv[i], "-schema")) ||
- (!strcmp(argv[i], "--schema"))) {
- i++;
- continue;
- }
- if ((!strcmp(argv[i], "-schematron")) ||
- (!strcmp(argv[i], "--schematron"))) {
- i++;
- continue;
- }
-#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
- if ((!strcmp(argv[i], "-pattern")) ||
- (!strcmp(argv[i], "--pattern"))) {
- i++;
- continue;
- }
-#endif
-#ifdef LIBXML_XPATH_ENABLED
- if ((!strcmp(argv[i], "-xpath")) ||
- (!strcmp(argv[i], "--xpath"))) {
- i++;
- continue;
- }
-#endif
- if ((!strcmp(argv[i], "-max-ampl")) ||
- (!strcmp(argv[i], "--max-ampl"))) {
- i++;
- continue;
+ if ((argv[i][0] == '-') && (strcmp(argv[i], "-") != 0)) {
+ i += skipArgs(argv[i]);
+ continue;
}
if ((timing) && (repeat))
startTimer();
- /* Remember file names. "-" means stdin. */
- if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
- if (repeat) {
- xmlParserCtxtPtr ctxt;
-
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- progresult = XMLLINT_ERR_MEM;
- goto error;
- }
- if (maxAmpl > 0)
- xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
+ if (repeat) {
+ xmlParserCtxtPtr ctxt;
- for (acount = 0;acount < repeat;acount++) {
+ ctxt = xmlNewParserCtxt();
+ if (ctxt == NULL) {
+ progresult = XMLLINT_ERR_MEM;
+ goto error;
+ }
+ if (maxAmpl > 0)
+ xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
+
+ for (acount = 0;acount < repeat;acount++) {
#ifdef LIBXML_READER_ENABLED
- if (stream != 0) {
- streamFile(argv[i]);
- } else {
+ if (stream != 0) {
+ streamFile(argv[i]);
+ } else {
#endif /* LIBXML_READER_ENABLED */
- if (sax) {
- testSAX(argv[i]);
- } else {
- parseAndPrintFile(argv[i], ctxt);
- }
+ if (sax) {
+ testSAX(argv[i]);
+ } else {
+ parseAndPrintFile(argv[i], ctxt);
+ }
#ifdef LIBXML_READER_ENABLED
- }
+ }
#endif /* LIBXML_READER_ENABLED */
- }
-
- xmlFreeParserCtxt(ctxt);
- } else {
- nbregister = 0;
+ }
+ xmlFreeParserCtxt(ctxt);
+ } else {
#ifdef LIBXML_READER_ENABLED
- if (stream != 0)
- streamFile(argv[i]);
- else
+ if (stream != 0)
+ streamFile(argv[i]);
+ else
#endif /* LIBXML_READER_ENABLED */
- if (sax) {
- testSAX(argv[i]);
- } else {
- parseAndPrintFile(argv[i], NULL);
- }
-
- if ((chkregister) && (nbregister != 0)) {
- fprintf(stderr, "Registration count off: %d\n", nbregister);
- progresult = XMLLINT_ERR_RDREGIS;
- }
- }
- files ++;
- if ((timing) && (repeat)) {
- endTimer("%d iterations", repeat);
- }
- }
+ if (sax) {
+ testSAX(argv[i]);
+ } else {
+ parseAndPrintFile(argv[i], NULL);
+ }
+ }
+ files ++;
+ if ((timing) && (repeat)) {
+ endTimer("%d iterations", repeat);
+ }
}
if (generate)
parseAndPrintFile(NULL, NULL);
if ((htmlout) && (!nowrap)) {
- xmlGenericError(xmlGenericErrorContext, "\n");
+ fprintf(ERR_STREAM, "