1 | /* |
---|
2 | * xmlcatalog.c : a small utility program to handle XML catalogs |
---|
3 | * |
---|
4 | * See Copyright for the status of this software. |
---|
5 | * |
---|
6 | * daniel@veillard.com |
---|
7 | */ |
---|
8 | |
---|
9 | #include "libxml.h" |
---|
10 | |
---|
11 | #include <string.h> |
---|
12 | #include <stdio.h> |
---|
13 | #include <stdarg.h> |
---|
14 | |
---|
15 | #ifdef HAVE_STDLIB_H |
---|
16 | #include <stdlib.h> |
---|
17 | #endif |
---|
18 | |
---|
19 | #ifdef HAVE_LIBREADLINE |
---|
20 | #include <readline/readline.h> |
---|
21 | #ifdef HAVE_LIBHISTORY |
---|
22 | #include <readline/history.h> |
---|
23 | #endif |
---|
24 | #endif |
---|
25 | |
---|
26 | #include <libxml/xmlmemory.h> |
---|
27 | #include <libxml/uri.h> |
---|
28 | #include <libxml/catalog.h> |
---|
29 | #include <libxml/parser.h> |
---|
30 | #include <libxml/globals.h> |
---|
31 | |
---|
32 | static int shell = 0; |
---|
33 | static int sgml = 0; |
---|
34 | static int noout = 0; |
---|
35 | static int create = 0; |
---|
36 | static int add = 0; |
---|
37 | static int del = 0; |
---|
38 | static int convert = 0; |
---|
39 | static int verbose = 0; |
---|
40 | static char *filename; |
---|
41 | |
---|
42 | #ifdef LIBXML_CATALOG_ENABLED |
---|
43 | |
---|
44 | #ifndef XML_SGML_DEFAULT_CATALOG |
---|
45 | #define XML_SGML_DEFAULT_CATALOG "/etc/sgml/catalog" |
---|
46 | #endif |
---|
47 | |
---|
48 | /************************************************************************ |
---|
49 | * * |
---|
50 | * Shell Interface * |
---|
51 | * * |
---|
52 | ************************************************************************/ |
---|
53 | /** |
---|
54 | * xmlShellReadline: |
---|
55 | * @prompt: the prompt value |
---|
56 | * |
---|
57 | * Read a string |
---|
58 | * |
---|
59 | * Returns a pointer to it or NULL on EOF the caller is expected to |
---|
60 | * free the returned string. |
---|
61 | */ |
---|
62 | static char * |
---|
63 | xmlShellReadline(const char *prompt) { |
---|
64 | #ifdef HAVE_LIBREADLINE |
---|
65 | char *line_read; |
---|
66 | |
---|
67 | /* Get a line from the user. */ |
---|
68 | line_read = readline (prompt); |
---|
69 | |
---|
70 | /* If the line has any text in it, save it on the history. */ |
---|
71 | if (line_read && *line_read) |
---|
72 | add_history (line_read); |
---|
73 | |
---|
74 | return (line_read); |
---|
75 | #else |
---|
76 | char line_read[501]; |
---|
77 | char *ret; |
---|
78 | int len; |
---|
79 | |
---|
80 | if (prompt != NULL) |
---|
81 | fprintf(stdout, "%s", prompt); |
---|
82 | if (!fgets(line_read, 500, stdin)) |
---|
83 | return(NULL); |
---|
84 | line_read[500] = 0; |
---|
85 | len = strlen(line_read); |
---|
86 | ret = (char *) malloc(len + 1); |
---|
87 | if (ret != NULL) { |
---|
88 | memcpy (ret, line_read, len + 1); |
---|
89 | } |
---|
90 | return(ret); |
---|
91 | #endif |
---|
92 | } |
---|
93 | |
---|
94 | static void usershell(void) { |
---|
95 | char *cmdline = NULL, *cur; |
---|
96 | int nbargs; |
---|
97 | char command[100]; |
---|
98 | char arg[400]; |
---|
99 | char *argv[20]; |
---|
100 | int i, ret; |
---|
101 | xmlChar *ans; |
---|
102 | |
---|
103 | while (1) { |
---|
104 | cmdline = xmlShellReadline("> "); |
---|
105 | if (cmdline == NULL) |
---|
106 | return; |
---|
107 | |
---|
108 | /* |
---|
109 | * Parse the command itself |
---|
110 | */ |
---|
111 | cur = cmdline; |
---|
112 | nbargs = 0; |
---|
113 | while ((*cur == ' ') || (*cur == '\t')) cur++; |
---|
114 | i = 0; |
---|
115 | while ((*cur != ' ') && (*cur != '\t') && |
---|
116 | (*cur != '\n') && (*cur != '\r')) { |
---|
117 | if (*cur == 0) |
---|
118 | break; |
---|
119 | command[i++] = *cur++; |
---|
120 | } |
---|
121 | command[i] = 0; |
---|
122 | if (i == 0) continue; |
---|
123 | nbargs++; |
---|
124 | |
---|
125 | /* |
---|
126 | * Parse the argument string |
---|
127 | */ |
---|
128 | memset(arg, 0, sizeof(arg)); |
---|
129 | while ((*cur == ' ') || (*cur == '\t')) cur++; |
---|
130 | i = 0; |
---|
131 | while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) { |
---|
132 | if (*cur == 0) |
---|
133 | break; |
---|
134 | arg[i++] = *cur++; |
---|
135 | } |
---|
136 | arg[i] = 0; |
---|
137 | if (i != 0) |
---|
138 | nbargs++; |
---|
139 | |
---|
140 | /* |
---|
141 | * Parse the arguments |
---|
142 | */ |
---|
143 | i = 0; |
---|
144 | nbargs = 0; |
---|
145 | cur = arg; |
---|
146 | memset(argv, 0, sizeof(argv)); |
---|
147 | while (*cur != 0) { |
---|
148 | while ((*cur == ' ') || (*cur == '\t')) cur++; |
---|
149 | if (*cur == '\'') { |
---|
150 | cur++; |
---|
151 | argv[i] = cur; |
---|
152 | while ((*cur != 0) && (*cur != '\'')) cur++; |
---|
153 | if (*cur == '\'') { |
---|
154 | *cur = 0; |
---|
155 | nbargs++; |
---|
156 | i++; |
---|
157 | cur++; |
---|
158 | } |
---|
159 | } else if (*cur == '"') { |
---|
160 | cur++; |
---|
161 | argv[i] = cur; |
---|
162 | while ((*cur != 0) && (*cur != '"')) cur++; |
---|
163 | if (*cur == '"') { |
---|
164 | *cur = 0; |
---|
165 | nbargs++; |
---|
166 | i++; |
---|
167 | cur++; |
---|
168 | } |
---|
169 | } else { |
---|
170 | argv[i] = cur; |
---|
171 | while ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) |
---|
172 | cur++; |
---|
173 | *cur = 0; |
---|
174 | nbargs++; |
---|
175 | i++; |
---|
176 | cur++; |
---|
177 | } |
---|
178 | } |
---|
179 | |
---|
180 | /* |
---|
181 | * start interpreting the command |
---|
182 | */ |
---|
183 | if (!strcmp(command, "exit")) |
---|
184 | break; |
---|
185 | if (!strcmp(command, "quit")) |
---|
186 | break; |
---|
187 | if (!strcmp(command, "bye")) |
---|
188 | break; |
---|
189 | if (!strcmp(command, "public")) { |
---|
190 | if (nbargs != 1) { |
---|
191 | printf("public requires 1 arguments\n"); |
---|
192 | } else { |
---|
193 | ans = xmlCatalogResolvePublic((const xmlChar *) argv[0]); |
---|
194 | if (ans == NULL) { |
---|
195 | printf("No entry for PUBLIC %s\n", argv[0]); |
---|
196 | } else { |
---|
197 | printf("%s\n", ans); |
---|
198 | xmlFree(ans); |
---|
199 | } |
---|
200 | } |
---|
201 | } else if (!strcmp(command, "system")) { |
---|
202 | if (nbargs != 1) { |
---|
203 | printf("system requires 1 arguments\n"); |
---|
204 | } else { |
---|
205 | ans = xmlCatalogResolveSystem((const xmlChar *) argv[0]); |
---|
206 | if (ans == NULL) { |
---|
207 | printf("No entry for SYSTEM %s\n", argv[0]); |
---|
208 | } else { |
---|
209 | printf("%s\n", ans); |
---|
210 | xmlFree(ans); |
---|
211 | } |
---|
212 | } |
---|
213 | } else if (!strcmp(command, "add")) { |
---|
214 | if (sgml) { |
---|
215 | if ((nbargs != 3) && (nbargs != 2)) { |
---|
216 | printf("add requires 2 or 3 arguments\n"); |
---|
217 | } else { |
---|
218 | if (argv[2] == NULL) |
---|
219 | ret = xmlCatalogAdd(BAD_CAST argv[0], NULL, |
---|
220 | BAD_CAST argv[1]); |
---|
221 | else |
---|
222 | ret = xmlCatalogAdd(BAD_CAST argv[0], BAD_CAST argv[1], |
---|
223 | BAD_CAST argv[2]); |
---|
224 | if (ret != 0) |
---|
225 | printf("add command failed\n"); |
---|
226 | } |
---|
227 | } else { |
---|
228 | if ((nbargs != 3) && (nbargs != 2)) { |
---|
229 | printf("add requires 2 or 3 arguments\n"); |
---|
230 | } else { |
---|
231 | if (argv[2] == NULL) |
---|
232 | ret = xmlCatalogAdd(BAD_CAST argv[0], NULL, |
---|
233 | BAD_CAST argv[1]); |
---|
234 | else |
---|
235 | ret = xmlCatalogAdd(BAD_CAST argv[0], BAD_CAST argv[1], |
---|
236 | BAD_CAST argv[2]); |
---|
237 | if (ret != 0) |
---|
238 | printf("add command failed\n"); |
---|
239 | } |
---|
240 | } |
---|
241 | } else if (!strcmp(command, "del")) { |
---|
242 | if (nbargs != 1) { |
---|
243 | printf("del requires 1\n"); |
---|
244 | } else { |
---|
245 | ret = xmlCatalogRemove(BAD_CAST argv[0]); |
---|
246 | if (ret <= 0) |
---|
247 | printf("del command failed\n"); |
---|
248 | |
---|
249 | } |
---|
250 | } else if (!strcmp(command, "resolve")) { |
---|
251 | if (nbargs != 2) { |
---|
252 | printf("resolve requires 2 arguments\n"); |
---|
253 | } else { |
---|
254 | ans = xmlCatalogResolve(BAD_CAST argv[0], |
---|
255 | BAD_CAST argv[1]); |
---|
256 | if (ans == NULL) { |
---|
257 | printf("Resolver failed to find an answer\n"); |
---|
258 | } else { |
---|
259 | printf("%s\n", ans); |
---|
260 | xmlFree(ans); |
---|
261 | } |
---|
262 | } |
---|
263 | } else if (!strcmp(command, "dump")) { |
---|
264 | if (nbargs != 0) { |
---|
265 | printf("dump has no arguments\n"); |
---|
266 | } else { |
---|
267 | xmlCatalogDump(stdout); |
---|
268 | } |
---|
269 | } else if (!strcmp(command, "debug")) { |
---|
270 | if (nbargs != 0) { |
---|
271 | printf("debug has no arguments\n"); |
---|
272 | } else { |
---|
273 | verbose++; |
---|
274 | xmlCatalogSetDebug(verbose); |
---|
275 | } |
---|
276 | } else if (!strcmp(command, "quiet")) { |
---|
277 | if (nbargs != 0) { |
---|
278 | printf("quiet has no arguments\n"); |
---|
279 | } else { |
---|
280 | if (verbose > 0) |
---|
281 | verbose--; |
---|
282 | xmlCatalogSetDebug(verbose); |
---|
283 | } |
---|
284 | } else { |
---|
285 | if (strcmp(command, "help")) { |
---|
286 | printf("Unrecognized command %s\n", command); |
---|
287 | } |
---|
288 | printf("Commands available:\n"); |
---|
289 | printf("\tpublic PublicID: make a PUBLIC identifier lookup\n"); |
---|
290 | printf("\tsystem SystemID: make a SYSTEM identifier lookup\n"); |
---|
291 | printf("\tresolve PublicID SystemID: do a full resolver lookup\n"); |
---|
292 | printf("\tadd 'type' 'orig' 'replace' : add an entry\n"); |
---|
293 | printf("\tdel 'values' : remove values\n"); |
---|
294 | printf("\tdump: print the current catalog state\n"); |
---|
295 | printf("\tdebug: increase the verbosity level\n"); |
---|
296 | printf("\tquiet: decrease the verbosity level\n"); |
---|
297 | printf("\texit: quit the shell\n"); |
---|
298 | } |
---|
299 | free(cmdline); /* not xmlFree here ! */ |
---|
300 | } |
---|
301 | } |
---|
302 | |
---|
303 | /************************************************************************ |
---|
304 | * * |
---|
305 | * Main * |
---|
306 | * * |
---|
307 | ************************************************************************/ |
---|
308 | static void usage(const char *name) { |
---|
309 | printf("Usage : %s [options] catalogfile entities...\n", name); |
---|
310 | printf("\tParse the catalog file and query it for the entities\n"); |
---|
311 | printf("\t--sgml : handle SGML Super catalogs for --add and --del\n"); |
---|
312 | printf("\t--shell : run a shell allowing interactive queries\n"); |
---|
313 | printf("\t--create : create a new catalog\n"); |
---|
314 | printf("\t--add 'type' 'orig' 'replace' : add an entry\n"); |
---|
315 | printf("\t--del 'values' : remove values\n"); |
---|
316 | printf("\t--noout: avoid dumping the result on stdout\n"); |
---|
317 | printf("\t used with add or del, it saves the catalog changes\n"); |
---|
318 | printf("\t and with --sgml it also updates the super catalog\n"); |
---|
319 | printf("\t-v --verbose : provide debug informations\n"); |
---|
320 | } |
---|
321 | int main(int argc, char **argv) { |
---|
322 | int i; |
---|
323 | int ret; |
---|
324 | int exit_value = 0; |
---|
325 | |
---|
326 | |
---|
327 | if (argc <= 1) { |
---|
328 | usage(argv[0]); |
---|
329 | return(1); |
---|
330 | } |
---|
331 | |
---|
332 | LIBXML_TEST_VERSION |
---|
333 | for (i = 1; i < argc ; i++) { |
---|
334 | if (!strcmp(argv[i], "-")) |
---|
335 | break; |
---|
336 | |
---|
337 | if (argv[i][0] != '-') |
---|
338 | break; |
---|
339 | if ((!strcmp(argv[i], "-verbose")) || |
---|
340 | (!strcmp(argv[i], "-v")) || |
---|
341 | (!strcmp(argv[i], "--verbose"))) { |
---|
342 | verbose++; |
---|
343 | xmlCatalogSetDebug(verbose); |
---|
344 | } else if ((!strcmp(argv[i], "-noout")) || |
---|
345 | (!strcmp(argv[i], "--noout"))) { |
---|
346 | noout = 1; |
---|
347 | } else if ((!strcmp(argv[i], "-shell")) || |
---|
348 | (!strcmp(argv[i], "--shell"))) { |
---|
349 | shell++; |
---|
350 | noout = 1; |
---|
351 | } else if ((!strcmp(argv[i], "-sgml")) || |
---|
352 | (!strcmp(argv[i], "--sgml"))) { |
---|
353 | sgml++; |
---|
354 | } else if ((!strcmp(argv[i], "-create")) || |
---|
355 | (!strcmp(argv[i], "--create"))) { |
---|
356 | create++; |
---|
357 | } else if ((!strcmp(argv[i], "-convert")) || |
---|
358 | (!strcmp(argv[i], "--convert"))) { |
---|
359 | convert++; |
---|
360 | } else if ((!strcmp(argv[i], "-add")) || |
---|
361 | (!strcmp(argv[i], "--add"))) { |
---|
362 | if (sgml) |
---|
363 | i += 2; |
---|
364 | else |
---|
365 | i += 3; |
---|
366 | add++; |
---|
367 | } else if ((!strcmp(argv[i], "-del")) || |
---|
368 | (!strcmp(argv[i], "--del"))) { |
---|
369 | i += 1; |
---|
370 | del++; |
---|
371 | } else { |
---|
372 | fprintf(stderr, "Unknown option %s\n", argv[i]); |
---|
373 | usage(argv[0]); |
---|
374 | return(1); |
---|
375 | } |
---|
376 | } |
---|
377 | |
---|
378 | for (i = 1; i < argc; i++) { |
---|
379 | if ((!strcmp(argv[i], "-add")) || |
---|
380 | (!strcmp(argv[i], "--add"))) { |
---|
381 | if (sgml) |
---|
382 | i += 2; |
---|
383 | else |
---|
384 | i += 3; |
---|
385 | continue; |
---|
386 | } else if ((!strcmp(argv[i], "-del")) || |
---|
387 | (!strcmp(argv[i], "--del"))) { |
---|
388 | i += 1; |
---|
389 | continue; |
---|
390 | } else if (argv[i][0] == '-') |
---|
391 | continue; |
---|
392 | filename = argv[i]; |
---|
393 | ret = xmlLoadCatalog(argv[i]); |
---|
394 | if ((ret < 0) && (create)) { |
---|
395 | xmlCatalogAdd(BAD_CAST "catalog", BAD_CAST argv[i], NULL); |
---|
396 | } |
---|
397 | break; |
---|
398 | } |
---|
399 | |
---|
400 | if (convert) |
---|
401 | ret = xmlCatalogConvert(); |
---|
402 | |
---|
403 | if ((add) || (del)) { |
---|
404 | for (i = 1; i < argc ; i++) { |
---|
405 | if (!strcmp(argv[i], "-")) |
---|
406 | break; |
---|
407 | |
---|
408 | if (argv[i][0] != '-') |
---|
409 | continue; |
---|
410 | if (strcmp(argv[i], "-add") && strcmp(argv[i], "--add") && |
---|
411 | strcmp(argv[i], "-del") && strcmp(argv[i], "--del")) |
---|
412 | continue; |
---|
413 | |
---|
414 | if (sgml) { |
---|
415 | /* |
---|
416 | * Maintenance of SGML catalogs. |
---|
417 | */ |
---|
418 | xmlCatalogPtr catal = NULL; |
---|
419 | xmlCatalogPtr super = NULL; |
---|
420 | |
---|
421 | catal = xmlLoadSGMLSuperCatalog(argv[i + 1]); |
---|
422 | |
---|
423 | if ((!strcmp(argv[i], "-add")) || |
---|
424 | (!strcmp(argv[i], "--add"))) { |
---|
425 | if (catal == NULL) |
---|
426 | catal = xmlNewCatalog(1); |
---|
427 | super = xmlLoadSGMLSuperCatalog(XML_SGML_DEFAULT_CATALOG); |
---|
428 | if (super == NULL) |
---|
429 | super = xmlNewCatalog(1); |
---|
430 | |
---|
431 | xmlACatalogAdd(catal, BAD_CAST "CATALOG", |
---|
432 | BAD_CAST argv[i + 2], NULL); |
---|
433 | xmlACatalogAdd(super, BAD_CAST "CATALOG", |
---|
434 | BAD_CAST argv[i + 1], NULL); |
---|
435 | } else { |
---|
436 | if (catal != NULL) |
---|
437 | ret = xmlACatalogRemove(catal, BAD_CAST argv[i + 2]); |
---|
438 | else |
---|
439 | ret = -1; |
---|
440 | if (ret < 0) { |
---|
441 | fprintf(stderr, "Failed to remove entry from %s\n", |
---|
442 | argv[i + 1]); |
---|
443 | exit_value = 1; |
---|
444 | } |
---|
445 | if ((noout) && (catal != NULL) && |
---|
446 | (xmlCatalogIsEmpty(catal))) { |
---|
447 | super = xmlLoadSGMLSuperCatalog( |
---|
448 | XML_SGML_DEFAULT_CATALOG); |
---|
449 | if (super != NULL) { |
---|
450 | ret = xmlACatalogRemove(super, |
---|
451 | BAD_CAST argv[i + 1]); |
---|
452 | if (ret < 0) { |
---|
453 | fprintf(stderr, |
---|
454 | "Failed to remove entry from %s\n", |
---|
455 | XML_SGML_DEFAULT_CATALOG); |
---|
456 | exit_value = 1; |
---|
457 | } |
---|
458 | } |
---|
459 | } |
---|
460 | } |
---|
461 | if (noout) { |
---|
462 | FILE *out; |
---|
463 | |
---|
464 | if (xmlCatalogIsEmpty(catal)) { |
---|
465 | remove(argv[i + 1]); |
---|
466 | } else { |
---|
467 | out = fopen(argv[i + 1], "w"); |
---|
468 | if (out == NULL) { |
---|
469 | fprintf(stderr, "could not open %s for saving\n", |
---|
470 | argv[i + 1]); |
---|
471 | exit_value = 2; |
---|
472 | noout = 0; |
---|
473 | } else { |
---|
474 | xmlACatalogDump(catal, out); |
---|
475 | fclose(out); |
---|
476 | } |
---|
477 | } |
---|
478 | if (super != NULL) { |
---|
479 | if (xmlCatalogIsEmpty(super)) { |
---|
480 | remove(XML_SGML_DEFAULT_CATALOG); |
---|
481 | } else { |
---|
482 | out = fopen(XML_SGML_DEFAULT_CATALOG, "w"); |
---|
483 | if (out == NULL) { |
---|
484 | fprintf(stderr, |
---|
485 | "could not open %s for saving\n", |
---|
486 | XML_SGML_DEFAULT_CATALOG); |
---|
487 | exit_value = 2; |
---|
488 | noout = 0; |
---|
489 | } else { |
---|
490 | |
---|
491 | xmlACatalogDump(super, out); |
---|
492 | fclose(out); |
---|
493 | } |
---|
494 | } |
---|
495 | } |
---|
496 | } else { |
---|
497 | xmlACatalogDump(catal, stdout); |
---|
498 | } |
---|
499 | i += 2; |
---|
500 | } else { |
---|
501 | if ((!strcmp(argv[i], "-add")) || |
---|
502 | (!strcmp(argv[i], "--add"))) { |
---|
503 | if ((argv[i + 3] == NULL) || (argv[i + 3][0] == 0)) |
---|
504 | ret = xmlCatalogAdd(BAD_CAST argv[i + 1], NULL, |
---|
505 | BAD_CAST argv[i + 2]); |
---|
506 | else |
---|
507 | ret = xmlCatalogAdd(BAD_CAST argv[i + 1], |
---|
508 | BAD_CAST argv[i + 2], |
---|
509 | BAD_CAST argv[i + 3]); |
---|
510 | if (ret != 0) { |
---|
511 | printf("add command failed\n"); |
---|
512 | exit_value = 3; |
---|
513 | } |
---|
514 | i += 3; |
---|
515 | } else if ((!strcmp(argv[i], "-del")) || |
---|
516 | (!strcmp(argv[i], "--del"))) { |
---|
517 | ret = xmlCatalogRemove(BAD_CAST argv[i + 1]); |
---|
518 | if (ret < 0) { |
---|
519 | fprintf(stderr, "Failed to remove entry %s\n", |
---|
520 | argv[i + 1]); |
---|
521 | exit_value = 1; |
---|
522 | } |
---|
523 | i += 1; |
---|
524 | } |
---|
525 | } |
---|
526 | } |
---|
527 | |
---|
528 | } else if (shell) { |
---|
529 | usershell(); |
---|
530 | } else { |
---|
531 | for (i++; i < argc; i++) { |
---|
532 | xmlURIPtr uri; |
---|
533 | xmlChar *ans; |
---|
534 | |
---|
535 | uri = xmlParseURI(argv[i]); |
---|
536 | if (uri == NULL) { |
---|
537 | ans = xmlCatalogResolvePublic((const xmlChar *) argv[i]); |
---|
538 | if (ans == NULL) { |
---|
539 | printf("No entry for PUBLIC %s\n", argv[i]); |
---|
540 | exit_value = 4; |
---|
541 | } else { |
---|
542 | printf("%s\n", ans); |
---|
543 | xmlFree(ans); |
---|
544 | } |
---|
545 | } else { |
---|
546 | xmlFreeURI(uri); |
---|
547 | ans = xmlCatalogResolveSystem((const xmlChar *) argv[i]); |
---|
548 | if (ans == NULL) { |
---|
549 | printf("No entry for SYSTEM %s\n", argv[i]); |
---|
550 | exit_value = 4; |
---|
551 | } else { |
---|
552 | printf("%s\n", ans); |
---|
553 | xmlFree(ans); |
---|
554 | } |
---|
555 | } |
---|
556 | } |
---|
557 | } |
---|
558 | if ((!sgml) && ((add) || (del) || (create) || (convert))) { |
---|
559 | if (noout) { |
---|
560 | FILE *out; |
---|
561 | |
---|
562 | out = fopen(filename, "w"); |
---|
563 | if (out == NULL) { |
---|
564 | fprintf(stderr, "could not open %s for saving\n", filename); |
---|
565 | exit_value = 2; |
---|
566 | noout = 0; |
---|
567 | } else { |
---|
568 | xmlCatalogDump(out); |
---|
569 | } |
---|
570 | } else { |
---|
571 | xmlCatalogDump(stdout); |
---|
572 | } |
---|
573 | } |
---|
574 | |
---|
575 | /* |
---|
576 | * Cleanup and check for memory leaks |
---|
577 | */ |
---|
578 | xmlCleanupParser(); |
---|
579 | xmlMemoryDump(); |
---|
580 | return(exit_value); |
---|
581 | } |
---|
582 | #else |
---|
583 | int main(int argc, char **argv) { |
---|
584 | fprintf(stderr, "libxml was not compiled with catalog support\n"); |
---|
585 | return(1); |
---|
586 | } |
---|
587 | #endif |
---|