VirtualBox

source: vbox/trunk/src/libs/libxml2-2.13.2/xmlcatalog.c@ 105770

Last change on this file since 105770 was 105420, checked in by vboxsync, 4 months ago

libxml2-2.12.6: Applied and adjusted our libxml2 changes to 2.12.6. bugref:10730

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette