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