Annotation of embedaddon/libxml2/testC14N.c, revision 1.1.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>