Annotation of embedaddon/libxml2/testC14N.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Canonical XML implementation test program
! 3: * (http://www.w3.org/TR/2001/REC-xml-c14n-20010315)
! 4: *
! 5: * See Copyright for the status of this software.
! 6: *
! 7: * Author: Aleksey Sanin <aleksey@aleksey.com>
! 8: */
! 9: #include "libxml.h"
! 10: #if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
! 11:
! 12: #include <stdio.h>
! 13: #include <string.h>
! 14: #ifdef HAVE_UNISTD_H
! 15: #include <unistd.h>
! 16: #endif
! 17: #ifdef HAVE_STDLIB_H
! 18: #include <stdlib.h>
! 19: #endif
! 20:
! 21: #include <libxml/xmlmemory.h>
! 22: #include <libxml/parser.h>
! 23: #include <libxml/xpath.h>
! 24: #include <libxml/xpathInternals.h>
! 25:
! 26: #include <libxml/c14n.h>
! 27:
! 28:
! 29: static void usage(const char *name) {
! 30: fprintf(stderr,
! 31: "Usage: %s <mode> <xml-file> [<xpath-expr>] [<inclusive-ns-list>]\n",
! 32: name);
! 33: fprintf(stderr, "where <mode> is one of following:\n");
! 34: fprintf(stderr,
! 35: "--with-comments \t XML file canonicalization v1.0 w comments \n");
! 36: fprintf(stderr,
! 37: "--without-comments \t XML file canonicalization v1.0 w/o comments\n");
! 38: fprintf(stderr,
! 39: "--1-1-with-comments \t XML file canonicalization v1.1 w comments\n");
! 40: fprintf(stderr,
! 41: "--1-1-without-comments \t XML file canonicalization v1.1 w/o comments\n");
! 42: fprintf(stderr,
! 43: "--exc-with-comments \t Exclusive XML file canonicalization v1.0 w comments\n");
! 44: fprintf(stderr,
! 45: "--exc-without-comments\t Exclusive XML file canonicalization v1.0 w/o comments\n");
! 46: }
! 47:
! 48: static xmlXPathObjectPtr
! 49: load_xpath_expr (xmlDocPtr parent_doc, const char* filename);
! 50:
! 51: static xmlChar **parse_list(xmlChar *str);
! 52:
! 53: /* static void print_xpath_nodes(xmlNodeSetPtr nodes); */
! 54:
! 55: static int
! 56: test_c14n(const char* xml_filename, int with_comments, int mode,
! 57: const char* xpath_filename, xmlChar **inclusive_namespaces) {
! 58: xmlDocPtr doc;
! 59: xmlXPathObjectPtr xpath = NULL;
! 60: xmlChar *result = NULL;
! 61: int ret;
! 62:
! 63: /*
! 64: * build an XML tree from a the file; we need to add default
! 65: * attributes and resolve all character and entities references
! 66: */
! 67: xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
! 68: xmlSubstituteEntitiesDefault(1);
! 69:
! 70: doc = xmlReadFile(xml_filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
! 71: if (doc == NULL) {
! 72: fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename);
! 73: return(-1);
! 74: }
! 75:
! 76: /*
! 77: * Check the document is of the right kind
! 78: */
! 79: if(xmlDocGetRootElement(doc) == NULL) {
! 80: fprintf(stderr,"Error: empty document for file \"%s\"\n", xml_filename);
! 81: xmlFreeDoc(doc);
! 82: return(-1);
! 83: }
! 84:
! 85: /*
! 86: * load xpath file if specified
! 87: */
! 88: if(xpath_filename) {
! 89: xpath = load_xpath_expr(doc, xpath_filename);
! 90: if(xpath == NULL) {
! 91: fprintf(stderr,"Error: unable to evaluate xpath expression\n");
! 92: xmlFreeDoc(doc);
! 93: return(-1);
! 94: }
! 95: }
! 96:
! 97: /*
! 98: * Canonical form
! 99: */
! 100: /* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */
! 101: ret = xmlC14NDocDumpMemory(doc,
! 102: (xpath) ? xpath->nodesetval : NULL,
! 103: mode, inclusive_namespaces,
! 104: with_comments, &result);
! 105: if(ret >= 0) {
! 106: if(result != NULL) {
! 107: write(1, result, ret);
! 108: xmlFree(result);
! 109: }
! 110: } else {
! 111: fprintf(stderr,"Error: failed to canonicalize XML file \"%s\" (ret=%d)\n", xml_filename, ret);
! 112: if(result != NULL) xmlFree(result);
! 113: xmlFreeDoc(doc);
! 114: return(-1);
! 115: }
! 116:
! 117: /*
! 118: * Cleanup
! 119: */
! 120: if(xpath != NULL) xmlXPathFreeObject(xpath);
! 121: xmlFreeDoc(doc);
! 122:
! 123: return(ret);
! 124: }
! 125:
! 126: int main(int argc, char **argv) {
! 127: int ret = -1;
! 128:
! 129: /*
! 130: * Init libxml
! 131: */
! 132: xmlInitParser();
! 133: LIBXML_TEST_VERSION
! 134:
! 135: /*
! 136: * Parse command line and process file
! 137: */
! 138: if( argc < 3 ) {
! 139: fprintf(stderr, "Error: wrong number of arguments.\n");
! 140: usage(argv[0]);
! 141: } else if(strcmp(argv[1], "--with-comments") == 0) {
! 142: ret = test_c14n(argv[2], 1, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL);
! 143: } else if(strcmp(argv[1], "--without-comments") == 0) {
! 144: ret = test_c14n(argv[2], 0, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL);
! 145: } else if(strcmp(argv[1], "--1-1-with-comments") == 0) {
! 146: ret = test_c14n(argv[2], 1, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL);
! 147: } else if(strcmp(argv[1], "--1-1-without-comments") == 0) {
! 148: ret = test_c14n(argv[2], 0, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL);
! 149: } else if(strcmp(argv[1], "--exc-with-comments") == 0) {
! 150: xmlChar **list;
! 151:
! 152: /* load exclusive namespace from command line */
! 153: list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL;
! 154: ret = test_c14n(argv[2], 1, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list);
! 155: if(list != NULL) xmlFree(list);
! 156: } else if(strcmp(argv[1], "--exc-without-comments") == 0) {
! 157: xmlChar **list;
! 158:
! 159: /* load exclusive namespace from command line */
! 160: list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL;
! 161: ret = test_c14n(argv[2], 0, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list);
! 162: if(list != NULL) xmlFree(list);
! 163: } else {
! 164: fprintf(stderr, "Error: bad option.\n");
! 165: usage(argv[0]);
! 166: }
! 167:
! 168: /*
! 169: * Shutdown libxml
! 170: */
! 171: xmlCleanupParser();
! 172: xmlMemoryDump();
! 173:
! 174: return((ret >= 0) ? 0 : 1);
! 175: }
! 176:
! 177: /*
! 178: * Macro used to grow the current buffer.
! 179: */
! 180: #define growBufferReentrant() { \
! 181: buffer_size *= 2; \
! 182: buffer = (xmlChar **) \
! 183: xmlRealloc(buffer, buffer_size * sizeof(xmlChar*)); \
! 184: if (buffer == NULL) { \
! 185: perror("realloc failed"); \
! 186: return(NULL); \
! 187: } \
! 188: }
! 189:
! 190: static xmlChar **
! 191: parse_list(xmlChar *str) {
! 192: xmlChar **buffer;
! 193: xmlChar **out = NULL;
! 194: int buffer_size = 0;
! 195: int len;
! 196:
! 197: if(str == NULL) {
! 198: return(NULL);
! 199: }
! 200:
! 201: len = xmlStrlen(str);
! 202: if((str[0] == '\'') && (str[len - 1] == '\'')) {
! 203: str[len - 1] = '\0';
! 204: str++;
! 205: }
! 206: /*
! 207: * allocate an translation buffer.
! 208: */
! 209: buffer_size = 1000;
! 210: buffer = (xmlChar **) xmlMalloc(buffer_size * sizeof(xmlChar*));
! 211: if (buffer == NULL) {
! 212: perror("malloc failed");
! 213: return(NULL);
! 214: }
! 215: out = buffer;
! 216:
! 217: while(*str != '\0') {
! 218: if (out - buffer > buffer_size - 10) {
! 219: int indx = out - buffer;
! 220:
! 221: growBufferReentrant();
! 222: out = &buffer[indx];
! 223: }
! 224: (*out++) = str;
! 225: while(*str != ',' && *str != '\0') ++str;
! 226: if(*str == ',') *(str++) = '\0';
! 227: }
! 228: (*out) = NULL;
! 229: return buffer;
! 230: }
! 231:
! 232: static xmlXPathObjectPtr
! 233: load_xpath_expr (xmlDocPtr parent_doc, const char* filename) {
! 234: xmlXPathObjectPtr xpath;
! 235: xmlDocPtr doc;
! 236: xmlChar *expr;
! 237: xmlXPathContextPtr ctx;
! 238: xmlNodePtr node;
! 239: xmlNsPtr ns;
! 240:
! 241: /*
! 242: * load XPath expr as a file
! 243: */
! 244: xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
! 245: xmlSubstituteEntitiesDefault(1);
! 246:
! 247: doc = xmlReadFile(filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
! 248: if (doc == NULL) {
! 249: fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);
! 250: return(NULL);
! 251: }
! 252:
! 253: /*
! 254: * Check the document is of the right kind
! 255: */
! 256: if(xmlDocGetRootElement(doc) == NULL) {
! 257: fprintf(stderr,"Error: empty document for file \"%s\"\n", filename);
! 258: xmlFreeDoc(doc);
! 259: return(NULL);
! 260: }
! 261:
! 262: node = doc->children;
! 263: while(node != NULL && !xmlStrEqual(node->name, (const xmlChar *)"XPath")) {
! 264: node = node->next;
! 265: }
! 266:
! 267: if(node == NULL) {
! 268: fprintf(stderr,"Error: XPath element expected in the file \"%s\"\n", filename);
! 269: xmlFreeDoc(doc);
! 270: return(NULL);
! 271: }
! 272:
! 273: expr = xmlNodeGetContent(node);
! 274: if(expr == NULL) {
! 275: fprintf(stderr,"Error: XPath content element is NULL \"%s\"\n", filename);
! 276: xmlFreeDoc(doc);
! 277: return(NULL);
! 278: }
! 279:
! 280: ctx = xmlXPathNewContext(parent_doc);
! 281: if(ctx == NULL) {
! 282: fprintf(stderr,"Error: unable to create new context\n");
! 283: xmlFree(expr);
! 284: xmlFreeDoc(doc);
! 285: return(NULL);
! 286: }
! 287:
! 288: /*
! 289: * Register namespaces
! 290: */
! 291: ns = node->nsDef;
! 292: while(ns != NULL) {
! 293: if(xmlXPathRegisterNs(ctx, ns->prefix, ns->href) != 0) {
! 294: fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->href);
! 295: xmlFree(expr);
! 296: xmlXPathFreeContext(ctx);
! 297: xmlFreeDoc(doc);
! 298: return(NULL);
! 299: }
! 300: ns = ns->next;
! 301: }
! 302:
! 303: /*
! 304: * Evaluate xpath
! 305: */
! 306: xpath = xmlXPathEvalExpression(expr, ctx);
! 307: if(xpath == NULL) {
! 308: fprintf(stderr,"Error: unable to evaluate xpath expression\n");
! 309: xmlFree(expr);
! 310: xmlXPathFreeContext(ctx);
! 311: xmlFreeDoc(doc);
! 312: return(NULL);
! 313: }
! 314:
! 315: /* print_xpath_nodes(xpath->nodesetval); */
! 316:
! 317: xmlFree(expr);
! 318: xmlXPathFreeContext(ctx);
! 319: xmlFreeDoc(doc);
! 320: return(xpath);
! 321: }
! 322:
! 323: /*
! 324: static void
! 325: print_xpath_nodes(xmlNodeSetPtr nodes) {
! 326: xmlNodePtr cur;
! 327: int i;
! 328:
! 329: if(nodes == NULL ){
! 330: fprintf(stderr, "Error: no nodes set defined\n");
! 331: return;
! 332: }
! 333:
! 334: fprintf(stderr, "Nodes Set:\n-----\n");
! 335: for(i = 0; i < nodes->nodeNr; ++i) {
! 336: if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
! 337: xmlNsPtr ns;
! 338:
! 339: ns = (xmlNsPtr)nodes->nodeTab[i];
! 340: cur = (xmlNodePtr)ns->next;
! 341: fprintf(stderr, "namespace \"%s\"=\"%s\" for node %s:%s\n",
! 342: ns->prefix, ns->href,
! 343: (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name);
! 344: } else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
! 345: cur = nodes->nodeTab[i];
! 346: fprintf(stderr, "element node \"%s:%s\"\n",
! 347: (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name);
! 348: } else {
! 349: cur = nodes->nodeTab[i];
! 350: fprintf(stderr, "node \"%s\": type %d\n", cur->name, cur->type);
! 351: }
! 352: }
! 353: }
! 354: */
! 355:
! 356: #else
! 357: #include <stdio.h>
! 358: int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
! 359: printf("%s : XPath/Canonicalization and output support not compiled in\n", argv[0]);
! 360: return(0);
! 361: }
! 362: #endif /* LIBXML_C14N_ENABLED */
! 363:
! 364:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>