version 1.11, 1999/12/21 17:53:00
|
version 1.12, 1999/12/28 15:31:14
|
Line 13
|
Line 13
|
#include "config.h" |
#include "config.h" |
#endif |
#endif |
#include <stdio.h> |
#include <stdio.h> |
|
#ifdef HAVE_STDLIB_H |
|
#include <stdlib.h> |
|
#endif |
|
#include "xmlmemory.h" |
#include "tree.h" |
#include "tree.h" |
#include "parser.h" |
#include "parser.h" |
#include "debugXML.h" |
#include "debugXML.h" |
|
#include "HTMLtree.h" |
|
#include "HTMLparser.h" |
|
|
#define IS_BLANK(c) \ |
#define IS_BLANK(c) \ |
(((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == ' ')) |
(((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == ' ')) |
Line 43 void xmlDebugDumpNamespace(FILE *output,
|
Line 49 void xmlDebugDumpNamespace(FILE *output,
|
if (ns->prefix != NULL) |
if (ns->prefix != NULL) |
fprintf(output, "namespace %s href=", ns->prefix); |
fprintf(output, "namespace %s href=", ns->prefix); |
else |
else |
fprintf(output, "default namespace href=", ns->prefix); |
fprintf(output, "default namespace href="); |
|
|
xmlDebugDumpString(output, ns->href); |
xmlDebugDumpString(output, ns->href); |
fprintf(output, "\n"); |
fprintf(output, "\n"); |
Line 217 void xmlDebugDumpNodeList(FILE *output,
|
Line 223 void xmlDebugDumpNodeList(FILE *output,
|
} |
} |
|
|
|
|
void xmlDebugDumpDocument(FILE *output, xmlDocPtr doc) { |
void xmlDebugDumpDocumentHead(FILE *output, xmlDocPtr doc) { |
if (output == NULL) output = stdout; |
if (output == NULL) output = stdout; |
if (doc == NULL) { |
if (doc == NULL) { |
fprintf(output, "DOCUMENT == NULL !\n"); |
fprintf(output, "DOCUMENT == NULL !\n"); |
Line 286 void xmlDebugDumpDocument(FILE *output,
|
Line 292 void xmlDebugDumpDocument(FILE *output,
|
fprintf(output, "standalone=true\n"); |
fprintf(output, "standalone=true\n"); |
if (doc->oldNs != NULL) |
if (doc->oldNs != NULL) |
xmlDebugDumpNamespaceList(output, doc->oldNs, 0); |
xmlDebugDumpNamespaceList(output, doc->oldNs, 0); |
if (doc->root != NULL) |
|
xmlDebugDumpNodeList(output, doc->root, 1); |
|
} |
} |
|
|
|
void xmlDebugDumpDocument(FILE *output, xmlDocPtr doc) { |
|
if (output == NULL) output = stdout; |
|
if (doc == NULL) { |
|
fprintf(output, "DOCUMENT == NULL !\n"); |
|
return; |
|
} |
|
xmlDebugDumpDocumentHead(output, doc); |
|
if (((doc->type == XML_DOCUMENT_NODE) || |
|
(doc->type == XML_HTML_DOCUMENT_NODE)) && |
|
(doc->root != NULL)) |
|
xmlDebugDumpNodeList(output, doc->root, 1); |
|
} |
|
|
void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) { |
void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) { |
int i; |
int i; |
xmlEntityPtr cur; |
xmlEntityPtr cur; |
Line 422 void xmlDebugDumpEntities(FILE *output,
|
Line 439 void xmlDebugDumpEntities(FILE *output,
|
} else |
} else |
fprintf(output, "No entities in external subset\n"); |
fprintf(output, "No entities in external subset\n"); |
} |
} |
|
|
|
static int xmlLsCountNode(xmlNodePtr node) { |
|
int ret = 0; |
|
xmlNodePtr list = NULL; |
|
|
|
switch (node->type) { |
|
case XML_ELEMENT_NODE: |
|
list = node->childs; |
|
break; |
|
case XML_DOCUMENT_NODE: |
|
case XML_HTML_DOCUMENT_NODE: |
|
list = ((xmlDocPtr) node)->root; |
|
break; |
|
case XML_ATTRIBUTE_NODE: |
|
list = ((xmlAttrPtr) node)->val; |
|
break; |
|
case XML_TEXT_NODE: |
|
case XML_CDATA_SECTION_NODE: |
|
case XML_PI_NODE: |
|
case XML_COMMENT_NODE: |
|
if (node->content != NULL) { |
|
#ifndef XML_USE_BUFFER_CONTENT |
|
ret = xmlStrlen(node->content); |
|
#else |
|
ret = xmlBufferLength(node->content); |
|
#endif |
|
} |
|
break; |
|
case XML_ENTITY_REF_NODE: |
|
case XML_DOCUMENT_TYPE_NODE: |
|
case XML_ENTITY_NODE: |
|
case XML_DOCUMENT_FRAG_NODE: |
|
case XML_NOTATION_NODE: |
|
ret = 1; |
|
break; |
|
} |
|
for (;list != NULL;ret++) |
|
list = list->next; |
|
return(ret); |
|
} |
|
|
|
void xmlLsOneNode(FILE *output, xmlNodePtr node) { |
|
switch (node->type) { |
|
case XML_ELEMENT_NODE: |
|
fprintf(output, "-"); |
|
break; |
|
case XML_ATTRIBUTE_NODE: |
|
fprintf(output, "a"); |
|
break; |
|
case XML_TEXT_NODE: |
|
fprintf(output, "t"); |
|
break; |
|
case XML_CDATA_SECTION_NODE: |
|
fprintf(output, "c"); |
|
break; |
|
case XML_ENTITY_REF_NODE: |
|
fprintf(output, "e"); |
|
break; |
|
case XML_ENTITY_NODE: |
|
fprintf(output, "E"); |
|
break; |
|
case XML_PI_NODE: |
|
fprintf(output, "p"); |
|
break; |
|
case XML_COMMENT_NODE: |
|
fprintf(output, "c"); |
|
break; |
|
case XML_DOCUMENT_NODE: |
|
fprintf(output, "d"); |
|
break; |
|
case XML_HTML_DOCUMENT_NODE: |
|
fprintf(output, "h"); |
|
break; |
|
case XML_DOCUMENT_TYPE_NODE: |
|
fprintf(output, "T"); |
|
break; |
|
case XML_DOCUMENT_FRAG_NODE: |
|
fprintf(output, "F"); |
|
break; |
|
case XML_NOTATION_NODE: |
|
fprintf(output, "N"); |
|
break; |
|
default: |
|
fprintf(output, "?"); |
|
} |
|
if (node->properties != NULL) |
|
fprintf(output, "a"); |
|
else |
|
fprintf(output, "-"); |
|
if (node->nsDef != NULL) |
|
fprintf(output, "n"); |
|
else |
|
fprintf(output, "-"); |
|
|
|
fprintf(output, " %8d ", xmlLsCountNode(node)); |
|
|
|
switch (node->type) { |
|
case XML_ELEMENT_NODE: |
|
if (node->name != NULL) |
|
fprintf(output, "%s", node->name); |
|
break; |
|
case XML_ATTRIBUTE_NODE: |
|
if (node->name != NULL) |
|
fprintf(output, "%s", node->name); |
|
break; |
|
case XML_TEXT_NODE: |
|
if (node->content != NULL) { |
|
#ifndef XML_USE_BUFFER_CONTENT |
|
xmlDebugDumpString(output, node->content); |
|
#else |
|
xmlDebugDumpString(output, xmlBufferContent(node->content)); |
|
#endif |
|
} |
|
break; |
|
case XML_CDATA_SECTION_NODE: |
|
break; |
|
case XML_ENTITY_REF_NODE: |
|
if (node->name != NULL) |
|
fprintf(output, "%s", node->name); |
|
break; |
|
case XML_ENTITY_NODE: |
|
if (node->name != NULL) |
|
fprintf(output, "%s", node->name); |
|
break; |
|
case XML_PI_NODE: |
|
if (node->name != NULL) |
|
fprintf(output, "%s", node->name); |
|
break; |
|
case XML_COMMENT_NODE: |
|
break; |
|
case XML_DOCUMENT_NODE: |
|
break; |
|
case XML_HTML_DOCUMENT_NODE: |
|
break; |
|
case XML_DOCUMENT_TYPE_NODE: |
|
break; |
|
case XML_DOCUMENT_FRAG_NODE: |
|
break; |
|
case XML_NOTATION_NODE: |
|
break; |
|
default: |
|
if (node->name != NULL) |
|
fprintf(output, "%s", node->name); |
|
} |
|
fprintf(output, "\n"); |
|
} |
|
|
|
/**************************************************************** |
|
* * |
|
* The XML shell related functions * |
|
* * |
|
****************************************************************/ |
|
|
|
/* |
|
* TODO: Improvement/cleanups for the XML shell |
|
* - allow to shell out an editor on a subpart |
|
* - cleanup function registrations (with help) and calling |
|
* - provide registration routines |
|
*/ |
|
|
|
/** |
|
* xmlShellList: |
|
* @ctxt: the shell context |
|
* @arg: unused |
|
* @node: a node |
|
* @node2: unused |
|
* |
|
* Implements the XML shell function "ls" |
|
* Does an Unix like listing of the given node (like a directory) |
|
* |
|
* Returns 0 |
|
*/ |
|
int |
|
xmlShellList(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node, |
|
xmlNodePtr node2) { |
|
xmlNodePtr cur; |
|
|
|
if ((node->type == XML_DOCUMENT_NODE) || |
|
(node->type == XML_HTML_DOCUMENT_NODE)) { |
|
cur = ((xmlDocPtr) node)->root; |
|
} else if (node->childs != NULL) { |
|
cur = node->childs; |
|
} else { |
|
xmlLsOneNode(stdout, node); |
|
return(0); |
|
} |
|
while (cur != NULL) { |
|
xmlLsOneNode(stdout, cur); |
|
cur = cur->next; |
|
} |
|
return(0); |
|
} |
|
|
|
/** |
|
* xmlShellDir: |
|
* @ctxt: the shell context |
|
* @arg: unused |
|
* @node: a node |
|
* @node2: unused |
|
* |
|
* Implements the XML shell function "dir" |
|
* dumps informations about the node (namespace, attributes, content). |
|
* |
|
* Returns 0 |
|
*/ |
|
int |
|
xmlShellDir(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node, |
|
xmlNodePtr node2) { |
|
if ((node->type == XML_DOCUMENT_NODE) || |
|
(node->type == XML_HTML_DOCUMENT_NODE)) { |
|
xmlDebugDumpDocumentHead(stdout, (xmlDocPtr) node); |
|
} else if (node->type == XML_ATTRIBUTE_NODE) { |
|
xmlDebugDumpAttr(stdout, (xmlAttrPtr) node, 0); |
|
} else { |
|
xmlDebugDumpOneNode(stdout, node, 0); |
|
} |
|
return(0); |
|
} |
|
|
|
/** |
|
* xmlShellCat: |
|
* @ctxt: the shell context |
|
* @arg: unused |
|
* @node: a node |
|
* @node2: unused |
|
* |
|
* Implements the XML shell function "cat" |
|
* dumps the serialization node content (XML or HTML). |
|
* |
|
* Returns 0 |
|
*/ |
|
int |
|
xmlShellCat(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node, |
|
xmlNodePtr node2) { |
|
xmlElemDump(stdout, ctxt->doc, node); |
|
printf("\n"); |
|
return(0); |
|
} |
|
|
|
/** |
|
* xmlShellLoad: |
|
* @ctxt: the shell context |
|
* @filename: the file name |
|
* @node: unused |
|
* @node2: unused |
|
* |
|
* Implements the XML shell function "load" |
|
* loads a new document specified by the filename |
|
* |
|
* Returns 0 or -1 if loading failed |
|
*/ |
|
int |
|
xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node, |
|
xmlNodePtr node2) { |
|
xmlDocPtr doc; |
|
int html = 0; |
|
|
|
if (ctxt->doc != NULL) |
|
html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE); |
|
|
|
if (html) { |
|
doc = htmlParseFile(filename, NULL); |
|
} else { |
|
doc = xmlParseFile(filename); |
|
} |
|
if (doc != NULL) { |
|
if (ctxt->loaded == 1) { |
|
xmlFreeDoc(ctxt->doc); |
|
} |
|
ctxt->loaded = 1; |
|
xmlXPathFreeContext(ctxt->pctxt); |
|
xmlFree(ctxt->filename); |
|
ctxt->doc = doc; |
|
ctxt->node = (xmlNodePtr) doc; |
|
ctxt->pctxt = xmlXPathNewContext(doc); |
|
ctxt->filename = (char *) xmlStrdup((xmlChar *) filename); |
|
} else |
|
return(-1); |
|
return(0); |
|
} |
|
|
|
/** |
|
* xmlShellWrite: |
|
* @ctxt: the shell context |
|
* @filename: the file name |
|
* @node: a node in the tree |
|
* @node2: unused |
|
* |
|
* Implements the XML shell function "write" |
|
* Write the current node to the filename, it saves the serailization |
|
* of the subtree under the @node specified |
|
* |
|
* Returns 0 or -1 in case of error |
|
*/ |
|
int |
|
xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node, |
|
xmlNodePtr node2) { |
|
if (node == NULL) |
|
return(-1); |
|
if ((filename == NULL) || (filename[0] == 0)) { |
|
fprintf(stderr, "Write command requires a filename argument\n"); |
|
return(-1); |
|
} |
|
#ifdef W_OK |
|
if (access((char *) filename, W_OK)) { |
|
fprintf(stderr, "Cannot write to %s\n", filename); |
|
return(-1); |
|
} |
|
#endif |
|
switch(node->type) { |
|
case XML_DOCUMENT_NODE: |
|
if (xmlSaveFile((char *) filename, ctxt->doc) < -1) { |
|
fprintf(stderr, "Failed to write to %s\n", filename); |
|
return(-1); |
|
} |
|
break; |
|
case XML_HTML_DOCUMENT_NODE: |
|
if (htmlSaveFile((char *) filename, ctxt->doc) < 0) { |
|
fprintf(stderr, "Failed to write to %s\n", filename); |
|
return(-1); |
|
} |
|
break; |
|
default: { |
|
FILE *f; |
|
|
|
f = fopen((char *) filename, "w"); |
|
if (f == NULL) { |
|
fprintf(stderr, "Failed to write to %s\n", filename); |
|
return(-1); |
|
} |
|
xmlElemDump(f, ctxt->doc, node); |
|
fclose(f); |
|
} |
|
} |
|
return(0); |
|
} |
|
|
|
/** |
|
* xmlShellSave: |
|
* @ctxt: the shell context |
|
* @filename: the file name (optionnal) |
|
* @node: unused |
|
* @node2: unused |
|
* |
|
* Implements the XML shell function "save" |
|
* Write the current document to the filename, or it's original name |
|
* |
|
* Returns 0 or -1 in case of error |
|
*/ |
|
int |
|
xmlShellSave(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node, |
|
xmlNodePtr node2) { |
|
if (ctxt->doc == NULL) |
|
return(-1); |
|
if ((filename == NULL) || (filename[0] == 0)) |
|
filename = ctxt->filename; |
|
#ifdef W_OK |
|
if (access((char *) filename, W_OK)) { |
|
fprintf(stderr, "Cannot save to %s\n", filename); |
|
return(-1); |
|
} |
|
#endif |
|
switch(ctxt->doc->type) { |
|
case XML_DOCUMENT_NODE: |
|
if (xmlSaveFile((char *) filename, ctxt->doc) < 0) { |
|
fprintf(stderr, "Failed to save to %s\n", filename); |
|
} |
|
break; |
|
case XML_HTML_DOCUMENT_NODE: |
|
if (htmlSaveFile((char *) filename, ctxt->doc) < 0) { |
|
fprintf(stderr, "Failed to save to %s\n", filename); |
|
} |
|
break; |
|
default: |
|
fprintf(stderr, |
|
"To save to subparts of a document use the 'write' command\n"); |
|
return(-1); |
|
|
|
} |
|
return(0); |
|
} |
|
|
|
/** |
|
* xmlShellValidate: |
|
* @ctxt: the shell context |
|
* @dtd: the DTD URI (optionnal) |
|
* @node: unused |
|
* @node2: unused |
|
* |
|
* Implements the XML shell function "validate" |
|
* Validate the document, if a DTD path is provided, then the validation |
|
* is done against the given DTD. |
|
* |
|
* Returns 0 or -1 in case of error |
|
*/ |
|
int |
|
xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd, xmlNodePtr node, |
|
xmlNodePtr node2) { |
|
xmlValidCtxt vctxt; |
|
int res = -1; |
|
|
|
vctxt.userData = stderr; |
|
vctxt.error = (xmlValidityErrorFunc) fprintf; |
|
vctxt.warning = (xmlValidityWarningFunc) fprintf; |
|
|
|
if ((dtd == NULL) || (dtd[0] == 0)) { |
|
res = xmlValidateDocument(&vctxt, ctxt->doc); |
|
} else { |
|
xmlDtdPtr subset; |
|
|
|
subset = xmlParseDTD(NULL, (xmlChar *) dtd); |
|
if (subset != NULL) { |
|
res = xmlValidateDtd(&vctxt, ctxt->doc, subset); |
|
|
|
xmlFreeDtd(subset); |
|
} |
|
} |
|
return(res); |
|
} |
|
|
|
/** |
|
* xmlShellDu: |
|
* @ctxt: the shell context |
|
* @arg: unused |
|
* @tree: a node defining a subtree |
|
* @node2: unused |
|
* |
|
* Implements the XML shell function "du" |
|
* show the structure of the subtree under node @tree |
|
* If @tree is null, the command works on the current node. |
|
* |
|
* Returns 0 or -1 in case of error |
|
*/ |
|
int |
|
xmlShellDu(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr tree, |
|
xmlNodePtr node2) { |
|
xmlNodePtr node; |
|
int indent = 0,i; |
|
|
|
if (tree == NULL) return(-1); |
|
node = tree; |
|
while (node != NULL) { |
|
if ((node->type == XML_DOCUMENT_NODE) || |
|
(node->type == XML_HTML_DOCUMENT_NODE)) { |
|
printf("/\n"); |
|
} else if (node->type == XML_ELEMENT_NODE) { |
|
for (i = 0;i < indent;i++) |
|
printf(" "); |
|
printf("%s\n", node->name); |
|
} else { |
|
} |
|
|
|
/* |
|
* Browse the full subtree, deep first |
|
*/ |
|
|
|
if ((node->type == XML_DOCUMENT_NODE) || |
|
(node->type == XML_HTML_DOCUMENT_NODE)) { |
|
node = ((xmlDocPtr) node)->root; |
|
} else if (node->childs != NULL) { |
|
/* deep first */ |
|
node = node->childs; |
|
indent++; |
|
} else if ((node != tree) && (node->next != NULL)) { |
|
/* then siblings */ |
|
node = node->next; |
|
} else if (node != tree) { |
|
/* go up to parents->next if needed */ |
|
while (node != tree) { |
|
if (node->parent != NULL) { |
|
node = node->parent; |
|
indent--; |
|
} |
|
if ((node != tree) && (node->next != NULL)) { |
|
node = node->next; |
|
break; |
|
} |
|
if (node->parent == NULL) { |
|
node = NULL; |
|
break; |
|
} |
|
if (node == tree) { |
|
node = NULL; |
|
break; |
|
} |
|
} |
|
/* exit condition */ |
|
if (node == tree) |
|
node = NULL; |
|
} else |
|
node = NULL; |
|
} |
|
return(0); |
|
} |
|
|
|
/** |
|
* xmlShellPwd: |
|
* @ctxt: the shell context |
|
* @buffer: the output buffer |
|
* @tree: a node |
|
* @node2: unused |
|
* |
|
* Implements the XML shell function "pwd" |
|
* Show the full path from the root to the node, if needed building |
|
* thumblers when similar elements exists at a given ancestor level. |
|
* The output is compatible with XPath commands. |
|
* |
|
* Returns 0 or -1 in case of error |
|
*/ |
|
int |
|
xmlShellPwd(xmlShellCtxtPtr ctxt, char *buffer, xmlNodePtr node, |
|
xmlNodePtr node2) { |
|
xmlNodePtr cur, tmp, next; |
|
char buf[500]; |
|
char sep; |
|
const char *name; |
|
int occur = 0; |
|
|
|
buffer[0] = 0; |
|
if (node == NULL) return(-1); |
|
cur = node; |
|
do { |
|
name = ""; |
|
sep= '?'; |
|
occur = 0; |
|
if ((cur->type == XML_DOCUMENT_NODE) || |
|
(cur->type == XML_HTML_DOCUMENT_NODE)) { |
|
sep = '/'; |
|
next = NULL; |
|
} else if (cur->type == XML_ELEMENT_NODE) { |
|
sep = '/'; |
|
name = (const char *)cur->name; |
|
next = cur->parent; |
|
|
|
/* |
|
* Thumbler index computation |
|
*/ |
|
tmp = cur->prev; |
|
while (tmp != NULL) { |
|
if (!xmlStrcmp(cur->name, tmp->name)) |
|
occur++; |
|
tmp = tmp->prev; |
|
} |
|
if (occur == 0) { |
|
tmp = cur->next; |
|
while (tmp != NULL) { |
|
if (!xmlStrcmp(cur->name, tmp->name)) |
|
occur++; |
|
tmp = tmp->next; |
|
} |
|
if (occur != 0) occur = 1; |
|
} else |
|
occur++; |
|
} else if (cur->type == XML_ATTRIBUTE_NODE) { |
|
sep = '@'; |
|
name = (const char *) (((xmlAttrPtr) cur)->name); |
|
next = ((xmlAttrPtr) cur)->node; |
|
} else { |
|
next = cur->parent; |
|
} |
|
if (occur == 0) |
|
sprintf(buf, "%c%s%s", sep, name, buffer); |
|
else |
|
sprintf(buf, "%c%s[%d]%s", sep, name, occur, buffer); |
|
strcpy(buffer, buf); |
|
cur = next; |
|
} while (cur != NULL); |
|
return(0); |
|
} |
|
|
|
/** |
|
* xmlShell |
|
* @doc: the initial document |
|
* @filename: the output buffer |
|
* @input: the line reading function |
|
* @output: the output FILE* |
|
* |
|
* Implements the XML shell |
|
* This allow to load, validate, view, modify and save a document |
|
* using a environment similar to a UNIX commandline. |
|
*/ |
|
void |
|
xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, |
|
FILE *output) { |
|
char prompt[500] = "/ > "; |
|
char *cmdline = NULL; |
|
int nbargs; |
|
char command[100]; |
|
char arg[400]; |
|
xmlShellCtxtPtr ctxt; |
|
xmlXPathObjectPtr list; |
|
|
|
if (doc == NULL) |
|
return; |
|
if (filename == NULL) |
|
return; |
|
if (input == NULL) |
|
return; |
|
if (output == NULL) |
|
return; |
|
ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt)); |
|
if (ctxt == NULL) |
|
return; |
|
ctxt->loaded = 0; |
|
ctxt->doc = doc; |
|
ctxt->input = input; |
|
ctxt->output = output; |
|
ctxt->filename = (char *) xmlStrdup((xmlChar *) filename); |
|
ctxt->node = (xmlNodePtr) ctxt->doc; |
|
|
|
ctxt->pctxt = xmlXPathNewContext(ctxt->doc); |
|
if (ctxt->pctxt == NULL) { |
|
xmlFree(ctxt); |
|
return; |
|
} |
|
while (1) { |
|
if (ctxt->node == (xmlNodePtr) ctxt->doc) |
|
sprintf(prompt, "%s > ", "/"); |
|
else if (ctxt->node->name) |
|
sprintf(prompt, "%s > ", ctxt->node->name); |
|
else |
|
sprintf(prompt, "? > "); |
|
|
|
cmdline = ctxt->input(prompt); |
|
if (cmdline == NULL) break; |
|
|
|
command[0] = 0; |
|
arg[0] = 0; |
|
nbargs = sscanf(cmdline, "%s %s", command, arg); |
|
|
|
if (command[0] == 0) continue; |
|
if (!strcmp(command, "exit")) |
|
break; |
|
if (!strcmp(command, "quit")) |
|
break; |
|
if (!strcmp(command, "bye")) |
|
break; |
|
if (!strcmp(command, "validate")) { |
|
xmlShellValidate(ctxt, arg, NULL, NULL); |
|
} else if (!strcmp(command, "load")) { |
|
xmlShellLoad(ctxt, arg, NULL, NULL); |
|
} else if (!strcmp(command, "save")) { |
|
xmlShellSave(ctxt, arg, NULL, NULL); |
|
} else if (!strcmp(command, "write")) { |
|
xmlShellWrite(ctxt, arg, NULL, NULL); |
|
} else if (!strcmp(command, "free")) { |
|
if (arg[0] == 0) { |
|
xmlMemShow(stdout, 0); |
|
} else { |
|
int len = 0; |
|
sscanf(arg, "%d", &len); |
|
xmlMemShow(stdout, len); |
|
} |
|
} else if (!strcmp(command, "pwd")) { |
|
char dir[500]; |
|
if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL)) |
|
printf("%s\n", dir); |
|
} else if (!strcmp(command, "du")) { |
|
xmlShellDu(ctxt, NULL, ctxt->node, NULL); |
|
} else if ((!strcmp(command, "ls")) || |
|
(!strcmp(command, "dir"))) { |
|
int dir = (!strcmp(command, "dir")); |
|
if (arg[0] == 0) { |
|
if (dir) |
|
xmlShellDir(ctxt, NULL, ctxt->node, NULL); |
|
else |
|
xmlShellList(ctxt, NULL, ctxt->node, NULL); |
|
} else { |
|
ctxt->pctxt->node = ctxt->node; |
|
if (ctxt->pctxt->nodelist != NULL) |
|
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist); |
|
ctxt->pctxt->nodelist = xmlXPathNodeSetCreate(ctxt->node); |
|
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt); |
|
if (list != NULL) { |
|
switch (list->type) { |
|
case XPATH_UNDEFINED: |
|
fprintf(stderr, "%s: no such node\n", arg); |
|
break; |
|
case XPATH_NODESET: { |
|
int i; |
|
|
|
for (i = 0;i < list->nodesetval->nodeNr;i++) { |
|
if (dir) |
|
xmlShellDir(ctxt, NULL, |
|
list->nodesetval->nodeTab[i], NULL); |
|
else |
|
xmlShellList(ctxt, NULL, |
|
list->nodesetval->nodeTab[i], NULL); |
|
} |
|
break; |
|
} |
|
case XPATH_BOOLEAN: |
|
fprintf(stderr, "%s is a Boolean\n", arg); |
|
break; |
|
case XPATH_NUMBER: |
|
fprintf(stderr, "%s is a number\n", arg); |
|
break; |
|
case XPATH_STRING: |
|
fprintf(stderr, "%s is a string\n", arg); |
|
break; |
|
} |
|
xmlXPathFreeNodeSetList(list); |
|
} else { |
|
fprintf(stderr, "%s: no such node\n", arg); |
|
} |
|
if (ctxt->pctxt->nodelist != NULL) |
|
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist); |
|
ctxt->pctxt->nodelist = NULL; |
|
} |
|
} else if (!strcmp(command, "cd")) { |
|
if (arg[0] == 0) { |
|
ctxt->node = (xmlNodePtr) ctxt->doc; |
|
} else { |
|
ctxt->pctxt->node = ctxt->node; |
|
if (ctxt->pctxt->nodelist != NULL) |
|
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist); |
|
ctxt->pctxt->nodelist = xmlXPathNodeSetCreate(ctxt->node); |
|
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt); |
|
if (list != NULL) { |
|
switch (list->type) { |
|
case XPATH_UNDEFINED: |
|
fprintf(stderr, "%s: no such node\n", arg); |
|
break; |
|
case XPATH_NODESET: |
|
if (list->nodesetval->nodeNr == 1) { |
|
ctxt->node = list->nodesetval->nodeTab[0]; |
|
} else |
|
fprintf(stderr, "%s is a %d Node Set\n", |
|
arg, list->nodesetval->nodeNr); |
|
break; |
|
case XPATH_BOOLEAN: |
|
fprintf(stderr, "%s is a Boolean\n", arg); |
|
break; |
|
case XPATH_NUMBER: |
|
fprintf(stderr, "%s is a number\n", arg); |
|
break; |
|
case XPATH_STRING: |
|
fprintf(stderr, "%s is a string\n", arg); |
|
break; |
|
} |
|
xmlXPathFreeNodeSetList(list); |
|
} else { |
|
fprintf(stderr, "%s: no such node\n", arg); |
|
} |
|
if (ctxt->pctxt->nodelist != NULL) |
|
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist); |
|
ctxt->pctxt->nodelist = NULL; |
|
} |
|
} else if (!strcmp(command, "cat")) { |
|
if (arg[0] == 0) { |
|
xmlShellCat(ctxt, NULL, ctxt->node, NULL); |
|
} else { |
|
ctxt->pctxt->node = ctxt->node; |
|
if (ctxt->pctxt->nodelist != NULL) |
|
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist); |
|
ctxt->pctxt->nodelist = xmlXPathNodeSetCreate(ctxt->node); |
|
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt); |
|
if (list != NULL) { |
|
switch (list->type) { |
|
case XPATH_UNDEFINED: |
|
fprintf(stderr, "%s: no such node\n", arg); |
|
break; |
|
case XPATH_NODESET: { |
|
int i; |
|
|
|
for (i = 0;i < list->nodesetval->nodeNr;i++) { |
|
if (i > 0) printf(" -------\n"); |
|
xmlShellCat(ctxt, NULL, |
|
list->nodesetval->nodeTab[i], NULL); |
|
} |
|
break; |
|
} |
|
case XPATH_BOOLEAN: |
|
fprintf(stderr, "%s is a Boolean\n", arg); |
|
break; |
|
case XPATH_NUMBER: |
|
fprintf(stderr, "%s is a number\n", arg); |
|
break; |
|
case XPATH_STRING: |
|
fprintf(stderr, "%s is a string\n", arg); |
|
break; |
|
} |
|
xmlXPathFreeNodeSetList(list); |
|
} else { |
|
fprintf(stderr, "%s: no such node\n", arg); |
|
} |
|
if (ctxt->pctxt->nodelist != NULL) |
|
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist); |
|
ctxt->pctxt->nodelist = NULL; |
|
} |
|
} else { |
|
fprintf(stderr, "Unknown command %s\n", command); |
|
} |
|
free(cmdline); /* not xmlFree here ! */ |
|
} |
|
xmlXPathFreeContext(ctxt->pctxt); |
|
if (ctxt->loaded) { |
|
xmlFreeDoc(ctxt->doc); |
|
} |
|
xmlFree(ctxt); |
|
if (cmdline != NULL) |
|
free(cmdline); /* not xmlFree here ! */ |
|
} |
|
|