1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-28 00:21:53 +03:00

Massive XPath implementation cleanup:

- debugXML.c testXPath.c xpath.[ch]: got pissed by some nastyness
  in the XPath engine, rewrote large parts of it, now it's far
  cleaner and in sync with the REC not an old WD. Fixed a parsing
  problem in the interactive XML shell found when testing XPath.
Daniel
This commit is contained in:
Daniel Veillard
2000-10-05 16:30:11 +00:00
parent ac26030669
commit 55b91f2d5b
6 changed files with 790 additions and 607 deletions

View File

@ -1,3 +1,10 @@
Thu Oct 5 18:13:15 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
* debugXML.c testXPath.c xpath.[ch]: got pissed by some nastyness
in the XPath engine, rewrote large parts of it, now it's far
cleaner and in sync with the REC not an old WD. Fixed a parsing
problem in the interactive XML shell found when testing XPath.
Wed Oct 4 15:25:53 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org> Wed Oct 4 15:25:53 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
* debugXML.c testXPath.c xpath.[ch]: More work on XPath/Xpointer, * debugXML.c testXPath.c xpath.[ch]: More work on XPath/Xpointer,

View File

@ -1559,10 +1559,11 @@ void
xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
FILE *output) { FILE *output) {
char prompt[500] = "/ > "; char prompt[500] = "/ > ";
char *cmdline = NULL; char *cmdline = NULL, *cur;
int nbargs; int nbargs;
char command[100]; char command[100];
char arg[400]; char arg[400];
int i;
xmlShellCtxtPtr ctxt; xmlShellCtxtPtr ctxt;
xmlXPathObjectPtr list; xmlXPathObjectPtr list;
@ -1604,14 +1605,45 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
sprintf(prompt, "? > "); sprintf(prompt, "? > ");
prompt[sizeof(prompt) - 1] = 0; prompt[sizeof(prompt) - 1] = 0;
/*
* Get a new command line
*/
cmdline = ctxt->input(prompt); cmdline = ctxt->input(prompt);
if (cmdline == NULL) break; if (cmdline == NULL) break;
command[0] = 0; /*
arg[0] = 0; * Parse the command itself
nbargs = sscanf(cmdline, "%s %s", command, arg); */
cur = cmdline;
while ((*cur == ' ') || (*cur == '\t')) cur++;
i = 0;
while ((*cur != ' ') && (*cur != '\t') &&
(*cur != '\n') && (*cur != '\r')) {
if (*cur == 0)
break;
command[i++] = *cur++;
}
command[i] = 0;
if (i == 0) continue;
nbargs++;
if (command[0] == 0) continue; /*
* Parse the argument
*/
while ((*cur == ' ') || (*cur == '\t')) cur++;
i = 0;
while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
if (*cur == 0)
break;
arg[i++] = *cur++;
}
arg[i] = 0;
if (i != 0)
nbargs++;
/*
* start interpreting the command
*/
if (!strcmp(command, "exit")) if (!strcmp(command, "exit"))
break; break;
if (!strcmp(command, "quit")) if (!strcmp(command, "quit"))

View File

@ -23,6 +23,28 @@ typedef xmlXPathContext *xmlXPathContextPtr;
typedef struct _xmlXPathParserContext xmlXPathParserContext; typedef struct _xmlXPathParserContext xmlXPathParserContext;
typedef xmlXPathParserContext *xmlXPathParserContextPtr; typedef xmlXPathParserContext *xmlXPathParserContextPtr;
/**
* The set of XPath error codes
*/
typedef enum {
XPATH_EXPRESSION_OK = 0,
XPATH_NUMBER_ERROR,
XPATH_UNFINISHED_LITERAL_ERROR,
XPATH_START_LITERAL_ERROR,
XPATH_VARIABLE_REF_ERROR,
XPATH_UNDEF_VARIABLE_ERROR,
XPATH_INVALID_PREDICATE_ERROR,
XPATH_EXPR_ERROR,
XPATH_UNCLOSED_ERROR,
XPATH_UNKNOWN_FUNC_ERROR,
XPATH_INVALID_OPERAND,
XPATH_INVALID_TYPE,
XPATH_INVALID_ARITY,
XPATH_INVALID_CTXT_SIZE,
XPATH_INVALID_CTXT_POSITION
} xmlXPathError;
/* /*
* A node-set (an unordered collection of nodes without duplicates) * A node-set (an unordered collection of nodes without duplicates)
*/ */
@ -206,6 +228,47 @@ struct _xmlXPathParserContext {
typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs); typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
/************************************************************************
* *
* Helpers *
* *
************************************************************************/
#define CHECK_ERROR \
if (ctxt->error != XPATH_EXPRESSION_OK) return
#define CHECK_ERROR0 \
if (ctxt->error != XPATH_EXPRESSION_OK) return(0)
#define XP_ERROR(X) \
{ xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return; }
#define XP_ERROR0(X) \
{ xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return(0); }
#define CHECK_TYPE(typeval) \
if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \
XP_ERROR(XPATH_INVALID_TYPE) \
#define CHECK_ARITY(x) \
if (nargs != (x)) { \
XP_ERROR(XPATH_INVALID_ARITY); \
} \
void xmlXPatherror (xmlXPathParserContextPtr ctxt,
const char *file,
int line,
int no);
/**
* Utilities for implementing more functions
*/
xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
int valuePush (xmlXPathParserContextPtr ctxt,
xmlXPathObjectPtr value);
/************************************************************************ /************************************************************************
* * * *
* Public API * * Public API *
@ -245,6 +308,7 @@ xmlNodeSetPtr xmlXPathNodeSetCreate (xmlNodePtr val);
void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj); void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj);
void xmlXPathFreeNodeSet (xmlNodeSetPtr obj); void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -84,6 +84,24 @@ static xmlChar buffer[] =
</EXAMPLE>\n\ </EXAMPLE>\n\
"; ";
void xmlXPAthDebugDumpNode(FILE *output, xmlNodePtr cur) {
if (cur == NULL) {
fprintf(output, "Node is NULL !\n");
return;
}
if (cur == NULL)
fprintf(output, " NULL\n");
else if ((cur->type == XML_DOCUMENT_NODE) ||
(cur->type == XML_HTML_DOCUMENT_NODE))
fprintf(output, " /\n");
else if (cur->type == XML_ATTRIBUTE_NODE)
xmlDebugDumpAttr(output, (xmlAttrPtr)cur, 2);
else
xmlDebugDumpOneNode(output, cur, 2);
}
void xmlXPAthDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur) { void xmlXPAthDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur) {
int i; int i;
@ -96,18 +114,29 @@ void xmlXPAthDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur) {
fprintf(output, "Set contains %d nodes:\n", cur->nodeNr); fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
for (i = 0;i < cur->nodeNr;i++) { for (i = 0;i < cur->nodeNr;i++) {
fprintf(output, "%d", i + 1); fprintf(output, "%d", i + 1);
if (cur->nodeTab[i] == NULL) xmlXPAthDebugDumpNode(output, cur->nodeTab[i]);
fprintf(output, " NULL\n");
else if ((cur->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
(cur->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE))
fprintf(output, " /\n");
else if (cur->nodeTab[i]->type == XML_ATTRIBUTE_NODE)
xmlDebugDumpAttr(output, (xmlAttrPtr)cur->nodeTab[i], 2);
else
xmlDebugDumpOneNode(output, cur->nodeTab[i], 2);
} }
} }
#if defined(LIBXML_XPTR_ENABLED)
void xmlXPAthDebugDumpObject(FILE *output, xmlXPathObjectPtr cur);
void xmlXPAthDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur) {
int i;
if (cur == NULL) {
fprintf(output, "LocationSet is NULL !\n");
return;
}
fprintf(output, "Set contains %d ranges:\n", cur->locNr);
for (i = 0;i < cur->locNr;i++) {
fprintf(output, "%d", i + 1);
xmlXPAthDebugDumpObject(output, cur->locTab[i]);
}
}
#endif
void xmlXPAthDebugDumpObject(FILE *output, xmlXPathObjectPtr cur) { void xmlXPAthDebugDumpObject(FILE *output, xmlXPathObjectPtr cur) {
if (cur == NULL) { if (cur == NULL) {
fprintf(output, "Object is empty (NULL)\n"); fprintf(output, "Object is empty (NULL)\n");
@ -134,6 +163,30 @@ void xmlXPAthDebugDumpObject(FILE *output, xmlXPathObjectPtr cur) {
xmlDebugDumpString(output, cur->stringval); xmlDebugDumpString(output, cur->stringval);
fprintf(output, "\n"); fprintf(output, "\n");
break; break;
case XPATH_POINT:
fprintf(output, "Object is a point : index %d in node", cur->index);
xmlXPAthDebugDumpNode(output, (xmlNodePtr) cur->user);
fprintf(output, "\n");
break;
case XPATH_RANGE:
fprintf(output, "Object is a range : from");
if (cur->index >= 0)
fprintf(output, "index %d in ", cur->index);
fprintf(output, "node");
xmlXPAthDebugDumpNode(output, (xmlNodePtr) cur->user);
fprintf(output, " to ");
if (cur->index2 >= 0)
fprintf(output, "index %d in ", cur->index2);
fprintf(output, "node");
xmlXPAthDebugDumpNode(output, (xmlNodePtr) cur->user2);
fprintf(output, "\n");
case XPATH_LOCATIONSET:
#if defined(LIBXML_XPTR_ENABLED)
fprintf(output, "Object is a location set containing :");
xmlXPAthDebugDumpLocationSet(output, (xmlLocationSetPtr) cur->user);
#endif
case XPATH_USERS:
fprintf(output, "Object is user defined\n");
} }
} }

1145
xpath.c

File diff suppressed because it is too large Load Diff

64
xpath.h
View File

@ -23,6 +23,28 @@ typedef xmlXPathContext *xmlXPathContextPtr;
typedef struct _xmlXPathParserContext xmlXPathParserContext; typedef struct _xmlXPathParserContext xmlXPathParserContext;
typedef xmlXPathParserContext *xmlXPathParserContextPtr; typedef xmlXPathParserContext *xmlXPathParserContextPtr;
/**
* The set of XPath error codes
*/
typedef enum {
XPATH_EXPRESSION_OK = 0,
XPATH_NUMBER_ERROR,
XPATH_UNFINISHED_LITERAL_ERROR,
XPATH_START_LITERAL_ERROR,
XPATH_VARIABLE_REF_ERROR,
XPATH_UNDEF_VARIABLE_ERROR,
XPATH_INVALID_PREDICATE_ERROR,
XPATH_EXPR_ERROR,
XPATH_UNCLOSED_ERROR,
XPATH_UNKNOWN_FUNC_ERROR,
XPATH_INVALID_OPERAND,
XPATH_INVALID_TYPE,
XPATH_INVALID_ARITY,
XPATH_INVALID_CTXT_SIZE,
XPATH_INVALID_CTXT_POSITION
} xmlXPathError;
/* /*
* A node-set (an unordered collection of nodes without duplicates) * A node-set (an unordered collection of nodes without duplicates)
*/ */
@ -206,6 +228,47 @@ struct _xmlXPathParserContext {
typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs); typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
/************************************************************************
* *
* Helpers *
* *
************************************************************************/
#define CHECK_ERROR \
if (ctxt->error != XPATH_EXPRESSION_OK) return
#define CHECK_ERROR0 \
if (ctxt->error != XPATH_EXPRESSION_OK) return(0)
#define XP_ERROR(X) \
{ xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return; }
#define XP_ERROR0(X) \
{ xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return(0); }
#define CHECK_TYPE(typeval) \
if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \
XP_ERROR(XPATH_INVALID_TYPE) \
#define CHECK_ARITY(x) \
if (nargs != (x)) { \
XP_ERROR(XPATH_INVALID_ARITY); \
} \
void xmlXPatherror (xmlXPathParserContextPtr ctxt,
const char *file,
int line,
int no);
/**
* Utilities for implementing more functions
*/
xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
int valuePush (xmlXPathParserContextPtr ctxt,
xmlXPathObjectPtr value);
/************************************************************************ /************************************************************************
* * * *
* Public API * * Public API *
@ -245,6 +308,7 @@ xmlNodeSetPtr xmlXPathNodeSetCreate (xmlNodePtr val);
void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj); void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj);
void xmlXPathFreeNodeSet (xmlNodeSetPtr obj); void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif