Commit 55b91f2d authored by Daniel Veillard's avatar Daniel Veillard
Browse files

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
parent ac260306
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>
* debugXML.c testXPath.c xpath.[ch]: More work on XPath/Xpointer,
......
......@@ -1559,10 +1559,11 @@ void
xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
FILE *output) {
char prompt[500] = "/ > ";
char *cmdline = NULL;
char *cmdline = NULL, *cur;
int nbargs;
char command[100];
char arg[400];
int i;
xmlShellCtxtPtr ctxt;
xmlXPathObjectPtr list;
......@@ -1604,14 +1605,45 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
sprintf(prompt, "? > ");
prompt[sizeof(prompt) - 1] = 0;
/*
* Get a new command line
*/
cmdline = ctxt->input(prompt);
if (cmdline == NULL) break;
command[0] = 0;
arg[0] = 0;
nbargs = sscanf(cmdline, "%s %s", command, arg);
/*
* Parse the command itself
*/
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++;
/*
* 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++;
if (command[0] == 0) continue;
/*
* start interpreting the command
*/
if (!strcmp(command, "exit"))
break;
if (!strcmp(command, "quit"))
......
......@@ -23,6 +23,28 @@ typedef xmlXPathContext *xmlXPathContextPtr;
typedef struct _xmlXPathParserContext xmlXPathParserContext;
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)
*/
......@@ -206,6 +228,47 @@ struct _xmlXPathParserContext {
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 *
......@@ -245,6 +308,7 @@ xmlNodeSetPtr xmlXPathNodeSetCreate (xmlNodePtr val);
void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj);
void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
#ifdef __cplusplus
}
#endif
......
......@@ -84,6 +84,24 @@ static xmlChar buffer[] =
</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) {
int i;
......@@ -96,17 +114,28 @@ void xmlXPAthDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur) {
fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
for (i = 0;i < cur->nodeNr;i++) {
fprintf(output, "%d", i + 1);
if (cur->nodeTab[i] == NULL)
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);
xmlXPAthDebugDumpNode(output, cur->nodeTab[i]);
}
}
#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) {
if (cur == NULL) {
......@@ -134,6 +163,30 @@ void xmlXPAthDebugDumpObject(FILE *output, xmlXPathObjectPtr cur) {
xmlDebugDumpString(output, cur->stringval);
fprintf(output, "\n");
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");
}
}
......
This diff is collapsed.
......@@ -23,6 +23,28 @@ typedef xmlXPathContext *xmlXPathContextPtr;
typedef struct _xmlXPathParserContext xmlXPathParserContext;
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)
*/
......@@ -206,6 +228,47 @@ struct _xmlXPathParserContext {
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 *
......@@ -245,6 +308,7 @@ xmlNodeSetPtr xmlXPathNodeSetCreate (xmlNodePtr val);
void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj);
void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
#ifdef __cplusplus
}
#endif
......
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