Commit d96f6d34 authored by Daniel Veillard's avatar Daniel Veillard

cleaning up XPath error reporting that time. applied the two patches for

* error.c include/libxml/xmlerror.h include/libxml/xpath.h
  include/libxml/xpathInternals.h xpath.c: cleaning up XPath
  error reporting that time.
* threads.c: applied the two patches for TLS threads
  on Windows from Jesse Pelton
* parser.c: tiny safety patch for xmlStrPrintf() make sure the
  return is always zero terminated. Should also help detecting
  passing wrong buffer size easilly.
* result/VC/* result/valid/rss.xml.err result/valid/xlink.xml.err:
  updated the results to follow the errors string generated by
  last commit.
Daniel
parent 6edbfbbe
Tue Oct 7 23:19:39 CEST 2003 Daniel Veillard <daniel@veillard.com>
* error.c include/libxml/xmlerror.h include/libxml/xpath.h
include/libxml/xpathInternals.h xpath.c: cleaning up XPath
error reporting that time.
* threads.c: applied the two patches for TLS threads
on Windows from Jesse Pelton
* parser.c: tiny safety patch for xmlStrPrintf() make sure the
return is always zero terminated. Should also help detecting
passing wrong buffer size easilly.
* result/VC/* result/valid/rss.xml.err result/valid/xlink.xml.err:
updated the results to follow the errors string generated by
last commit.
Tue Oct 7 14:16:45 CEST 2003 Daniel Veillard <daniel@veillard.com>
* relaxng.c include/libxml/xmlerror.h: last cleanup of error
......
......@@ -262,13 +262,13 @@ xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
if (input != NULL) {
if (input->filename)
channel(data, "%s:%d: ", input->filename, input->line);
else
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
else if ((line != 0) && (domain == XML_FROM_PARSER))
channel(data, "Entity: line %d: ", line);
}
if (name != NULL) {
......@@ -362,11 +362,24 @@ xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
if (cur != NULL) {
if (cur->filename)
channel(data, "%s:%d: \n", cur->filename, cur->line);
else
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);
}
}
/**
......
......@@ -375,7 +375,29 @@ typedef enum {
XML_RNGP_VALUE_EMPTY,
XML_RNGP_VALUE_NO_CONTENT,
XML_RNGP_XMLNS_NAME,
XML_RNGP_XML_NS
XML_RNGP_XML_NS,
XML_XPATH_EXPRESSION_OK = 1200,
XML_XPATH_NUMBER_ERROR,
XML_XPATH_UNFINISHED_LITERAL_ERROR,
XML_XPATH_START_LITERAL_ERROR,
XML_XPATH_VARIABLE_REF_ERROR,
XML_XPATH_UNDEF_VARIABLE_ERROR,
XML_XPATH_INVALID_PREDICATE_ERROR,
XML_XPATH_EXPR_ERROR,
XML_XPATH_UNCLOSED_ERROR,
XML_XPATH_UNKNOWN_FUNC_ERROR,
XML_XPATH_INVALID_OPERAND,
XML_XPATH_INVALID_TYPE,
XML_XPATH_INVALID_ARITY,
XML_XPATH_INVALID_CTXT_SIZE,
XML_XPATH_INVALID_CTXT_POSITION,
XML_XPATH_MEMORY_ERROR,
XML_XPTR_SYNTAX_ERROR,
XML_XPTR_RESOURCE_ERROR,
XML_XPTR_SUB_RESOURCE_ERROR,
XML_XPATH_UNDEF_PREFIX_ERROR,
XML_XPATH_ENCODING_ERROR,
XML_XPATH_INVALID_CHAR_ERROR
} xmlParserErrors;
/**
......@@ -389,7 +411,16 @@ typedef enum {
*/
typedef void (*xmlGenericErrorFunc) (void *ctx,
const char *msg,
...);
...);
/**
* xmlStructuredErrorFunc:
* @userData: user provided data for the error callback
* @error: the error being raised.
*
* Signature of the function to use when there is an error and
* the module handles the new error reporting mechanism.
*/
typedef void (*xmlStructuredErrorFunc) (void *userData, xmlErrorPtr error);
/*
* Use the following function to reset the two global variables
......
......@@ -13,6 +13,7 @@
#define __XML_XPATH_H__
#include <libxml/xmlversion.h>
#include <libxml/xmlerror.h>
#include <libxml/tree.h>
#include <libxml/hash.h>
......@@ -253,6 +254,12 @@ struct _xmlXPathContext {
/* temporary namespace lists kept for walking the namespace axis */
xmlNsPtr *tmpNsList; /* Array of namespaces */
int tmpNsNr; /* number of namespace in scope */
/* error reporting mechanism */
void *userData; /* user specific data block */
xmlStructuredErrorFunc error; /* the callback in case of errors */
xmlError lastError; /* the last error */
xmlNodePtr debugNode; /* the source node XSLT */
};
/*
......
......@@ -250,8 +250,7 @@ XMLPUBFUN void * XMLCALL
* Macro to raise an XPath error and return.
*/
#define XP_ERROR(X) \
{ xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return; }
{ xmlXPathErr(ctxt, X); return; }
/**
* XP_ERROR0:
......@@ -260,8 +259,7 @@ XMLPUBFUN void * XMLCALL
* Macro to raise an XPath error and return 0.
*/
#define XP_ERROR0(X) \
{ xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return(0); }
{ xmlXPathErr(ctxt, X); return(0); }
/**
* CHECK_TYPE:
......@@ -377,6 +375,10 @@ XMLPUBFUN void XMLCALL
int line,
int no);
XMLPUBFUN void XMLCALL
xmlXPathErr (xmlXPathParserContextPtr ctxt,
int error);
#ifdef LIBXML_DEBUG_ENABLED
XMLPUBFUN void XMLCALL
xmlXPathDebugDumpObject (FILE *output,
......
......@@ -2449,6 +2449,7 @@ xmlStrPrintf(xmlChar *buf, int len, const xmlChar *msg, ...) {
va_start(args, msg);
ret = vsnprintf((char *) buf, len, (const char *) msg, args);
va_end(args);
buf[len - 1] = 0; /* be safe ! */
return(ret);
}
......
......@@ -7,6 +7,6 @@
./test/VC/AttributeDefaultLegal:8: validity error : Attribute doc of bad2: invalid default value
<!ATTLIST doc bad2 IDREFS "abc:1 1abc_2">
^
./test/VC/AttributeDefaultLegal:11: validity error : No declaration for attribute val of element doc
./test/VC/AttributeDefaultLegal:11: element doc: validity error : No declaration for attribute val of element doc
<doc val="v1"/>
^
./test/VC/ElementValid2:4: validity error : No declaration for element p
./test/VC/ElementValid2:4: element p: validity error : No declaration for element p
<doc><p/></doc>
^
./test/VC/ElementValid3:4: validity error : Element doc was declared EMPTY this one has content
./test/VC/ElementValid3:4: element doc: validity error : Element doc was declared EMPTY this one has content
<doc>Oops, this element was declared EMPTY</doc>
^
./test/VC/ElementValid4:7: validity error : Element c is not declared in doc list of possible children
./test/VC/ElementValid4:7: element doc: validity error : Element c is not declared in doc list of possible children
<doc> This <b>seems</b> Ok <a/> but this <c>was not declared</c></doc>
^
./test/VC/ElementValid5:7: validity error : Element doc content does not follow the DTD, expecting (a , b* , c+), got (a b c b)
./test/VC/ElementValid5:7: element doc: validity error : Element doc content does not follow the DTD, expecting (a , b* , c+), got (a b c b)
<doc><a/><b> but this</b><c>was not declared</c><b>seems</b></doc>
^
./test/VC/ElementValid6:7: validity error : Element doc content does not follow the DTD, expecting (a , b? , c+)?, got (a b)
./test/VC/ElementValid6:7: element doc: validity error : Element doc content does not follow the DTD, expecting (a , b? , c+)?, got (a b)
<doc><a/><b>lacks c</b></doc>
^
./test/VC/ElementValid7:7: validity error : Element doc content does not follow the DTD, expecting ((a | b)* , c+ , a , b? , c , a?), got (a b a c c a)
./test/VC/ElementValid7:7: element doc: validity error : Element doc content does not follow the DTD, expecting ((a | b)* , c+ , a , b? , c , a?), got (a b a c c a)
<doc><a/><b/><a/><c/><c/><a/></doc>
^
./test/VC/Enumeration:5: validity error : Value "v4" for attribute val of doc is not among the enumerated set
./test/VC/Enumeration:5: element doc: validity error : Value "v4" for attribute val of doc is not among the enumerated set
<doc val="v4"></doc>
^
./test/VC/NS2:9: validity error : No declaration for attribute attr of element doc
./test/VC/NS2:9: element doc: validity error : No declaration for attribute attr of element doc
<ns:doc ns:attr="val" xmlns:ns="http://www.example.org/test/">
^
./test/VC/NS3:9: validity error : Value for attribute xmlns of foo is different from default "http://example.com/fooo"
./test/VC/NS3:9: element foo: validity error : Value for attribute xmlns of foo is different from default "http://example.com/fooo"
xmlns="http://example.com/foo" xmlns:foo="http://example.com/fo" foo:info="toto"
^
./test/VC/NS3:9: validity error : Value for attribute xmlns of foo must be "http://example.com/fooo"
./test/VC/NS3:9: element foo: validity error : Value for attribute xmlns of foo must be "http://example.com/fooo"
xmlns="http://example.com/foo" xmlns:foo="http://example.com/fo" foo:info="toto"
^
./test/VC/NS3:9: validity error : Element foo namespace name for default namespace does not match the DTD
./test/VC/NS3:9: element foo: validity error : Element foo namespace name for default namespace does not match the DTD
mlns="http://example.com/foo" xmlns:foo="http://example.com/fo" foo:info="toto"/
^
./test/VC/OneID:4: validity error : Element doc has too may ID attributes defined : id
<!ATTLIST doc id ID #IMPLIED>
^
Element doc has too many ID attributes defined : id
./test/VC/OneID:0: validity error : Element doc has too many ID attributes defined : id
./test/VC/OneID:4: validity error : Element doc has 2 ID attribute defined in the internal subset : id
<!ATTLIST doc id ID #IMPLIED>
^
./test/VC/OneID2:3: validity error : Element doc has too may ID attributes defined : id
<!ATTLIST doc id ID #IMPLIED>
^
Element doc has too many ID attributes defined : id
Entity: line 0: validity error : Element doc has too many ID attributes defined : id
./test/VC/OneID2:3: validity error : Element doc has 2 ID attribute defined in the internal subset : id
<!ATTLIST doc id ID #IMPLIED>
^
test/VC/dtds/doc.dtd:2: validity error : Element doc has too may ID attributes defined : val
<!ATTLIST doc val ID #IMPLIED>
^
Element doc has too many ID attributes defined : val
./test/VC/OneID3:0: validity error : Element doc has too many ID attributes defined : val
test/VC/dtds/doc.dtd:2: validity error : Element doc has 2 ID attribute defined in the external subset : val
<!ATTLIST doc val ID #IMPLIED>
^
B<?xml version="1.0" encoding="utf-16"?>
B<?xml version="1.0" encoding="utf-16"?>
./test/valid/rss.xml:177: validity error : Element rss does not carry attribute version
./test/valid/rss.xml:177: element rss: validity error : Element rss does not carry attribute version
</rss>
^
./test/valid/xlink.xml:450: validity error : ID dt-arc already defined
./test/valid/xlink.xml:450: element termdef: validity error : ID dt-arc already defined
<p><termdef id="dt-arc" term="Arc">An <term>arc</term> is contained within an e
^
./test/valid/xlink.xml:530: validity error : IDREF attribute def references an unknown ID "dt-xlg"
./test/valid/xlink.xml:530: element termref: validity error : IDREF attribute def references an unknown ID "dt-xlg"
^
......@@ -336,7 +336,8 @@ xmlNewGlobalState(void)
#ifdef HAVE_WIN32_THREADS
#if !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC)
#if !defined(HAVE_COMPILER_TLS)
#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
typedef struct _xmlGlobalStateCleanupHelperParams
{
HANDLE thread;
......@@ -352,7 +353,20 @@ static void xmlGlobalStateCleanupHelper (void *p)
free(params);
_endthread();
}
#endif /* HAVE_COMPILER_TLS && LIBXML_STATIC */
#else /* LIBXML_STATIC && !LIBXML_STATIC_FOR_DLL */
typedef struct _xmlGlobalStateCleanupHelperParams
{
void *memory;
struct _xmlGlobalStateCleanupHelperParams * prev;
struct _xmlGlobalStateCleanupHelperParams * next;
} xmlGlobalStateCleanupHelperParams;
static xmlGlobalStateCleanupHelperParams * cleanup_helpers_head = NULL;
static CRITICAL_SECTION cleanup_helpers_cs;
#endif /* LIBXMLSTATIC && !LIBXML_STATIC_FOR_DLL */
#endif /* HAVE_COMPILER_TLS */
#endif /* HAVE_WIN32_THREADS */
/**
......@@ -387,23 +401,37 @@ xmlGetGlobalState(void)
return &tlstate;
#else /* HAVE_COMPILER_TLS */
xmlGlobalState *globalval;
xmlGlobalStateCleanupHelperParams * p;
if (run_once_init) {
run_once_init = 0;
xmlOnceInit();
}
if ((globalval = (xmlGlobalState *) TlsGetValue(globalkey)) == NULL) {
#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
globalval = (xmlGlobalState *)TlsGetValue(globalkey);
#else
p = (xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey);
globalval = (xmlGlobalState *)(p ? p->memory : NULL);
#endif
if (globalval == NULL) {
xmlGlobalState *tsd = xmlNewGlobalState();
#if defined(LIBXML_STATIC)
xmlGlobalStateCleanupHelperParams *p =
(xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
p = (xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
p->memory = tsd;
#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS);
#endif
TlsSetValue(globalkey, tsd);
#if defined(LIBXML_STATIC)
_beginthread(xmlGlobalStateCleanupHelper, 0, p);
#else
EnterCriticalSection(&cleanup_helpers_cs);
if (cleanup_helpers_head != NULL) {
cleanup_helpers_head->prev = p;
}
p->next = cleanup_helpers_head;
p->prev = NULL;
cleanup_helpers_head = p;
TlsSetValue(globalkey, p);
LeaveCriticalSection(&cleanup_helpers_cs);
#endif
return (tsd);
......@@ -513,6 +541,9 @@ xmlInitThreads(void)
#ifdef DEBUG_THREADS
xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n");
#endif
#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS)
InitializeCriticalSection(&cleanup_helpers_cs);
#endif
}
/**
......@@ -527,6 +558,24 @@ xmlCleanupThreads(void)
#ifdef DEBUG_THREADS
xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
#endif
#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS)
if (globalkey != TLS_OUT_OF_INDEXES) {
xmlGlobalStateCleanupHelperParams * p;
EnterCriticalSection(&cleanup_helpers_cs);
p = cleanup_helpers_head;
while (p != NULL) {
xmlGlobalStateCleanupHelperParams * temp = p;
p = p->next;
xmlFreeGlobalState(temp->memory);
free(temp);
}
cleanup_helpers_head = 0;
LeaveCriticalSection(&cleanup_helpers_cs);
TlsFree(globalkey);
globalkey = TLS_OUT_OF_INDEXES;
}
DeleteCriticalSection(&cleanup_helpers_cs);
#endif
}
#ifdef LIBXML_THREAD_ENABLED
......@@ -566,27 +615,39 @@ xmlOnceInit(void) {
*
* Returns TRUE always
*/
#if defined(HAVE_WIN32_THREADS) && !defined(LIBXML_STATIC)
#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
#if defined(LIBXML_STATIC_FOR_DLL)
BOOL WINAPI xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#else
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#endif
{
switch(fdwReason) {
case DLL_THREAD_DETACH:
if (globalkey != TLS_OUT_OF_INDEXES) {
xmlGlobalState *globalval = (xmlGlobalState *)TlsGetValue(globalkey);
if (globalval) {
xmlFreeGlobalState(globalval);
TlsSetValue(globalkey, NULL);
xmlGlobalState *globalval = NULL;
xmlGlobalStateCleanupHelperParams * p =
(xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey);
globalval = (xmlGlobalState *)(p ? p->memory : NULL);
if (globalval) {
xmlFreeGlobalState(globalval);
TlsSetValue(globalkey,NULL);
}
if (p)
{
EnterCriticalSection(&cleanup_helpers_cs);
if (p == cleanup_helpers_head)
cleanup_helpers_head = p->next;
else
p->prev->next = p->next;
if (p->next != NULL)
p->next->prev = p->prev;
LeaveCriticalSection(&cleanup_helpers_cs);
free(p);
}
}
break;
case DLL_PROCESS_DETACH:
if (globalkey != TLS_OUT_OF_INDEXES) {
TlsFree(globalkey);
globalkey = TLS_OUT_OF_INDEXES;
}
break;
}
return TRUE;
}
#endif
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment