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>