ReactOS 0.4.16-dev-338-g34e76ad
xmlcatalog.c
Go to the documentation of this file.
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#include <libxml/globals.h>
28
29#if defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
30static int shell = 0;
31static int sgml = 0;
32static int noout = 0;
33static int create = 0;
34static int add = 0;
35static int del = 0;
36static int convert = 0;
37static int no_super_update = 0;
38static int verbose = 0;
39static char *filename = NULL;
40
41
42#ifndef XML_SGML_DEFAULT_CATALOG
43#define XML_SGML_DEFAULT_CATALOG SYSCONFDIR "/sgml/catalog"
44#endif
45
46/************************************************************************
47 * *
48 * Shell Interface *
49 * *
50 ************************************************************************/
60static char *
61xmlShellReadline(const char *prompt) {
62#ifdef HAVE_LIBREADLINE
63 char *line_read;
64
65 /* Get a line from the user. */
66 line_read = readline (prompt);
67
68 /* If the line has any text in it, save it on the history. */
69 if (line_read && *line_read)
70 add_history (line_read);
71
72 return (line_read);
73#else
74 char line_read[501];
75 char *ret;
76 int len;
77
78 if (prompt != NULL)
79 fprintf(stdout, "%s", prompt);
81 if (!fgets(line_read, 500, stdin))
82 return(NULL);
83 line_read[500] = 0;
84 len = strlen(line_read);
85 ret = (char *) malloc(len + 1);
86 if (ret != NULL) {
87 memcpy (ret, line_read, len + 1);
88 }
89 return(ret);
90#endif
91}
92
93static void usershell(void) {
94 char *cmdline = NULL, *cur;
95 int nbargs;
96 char command[100];
97 char arg[400];
98 char *argv[20];
99 int i, ret;
100 xmlChar *ans;
101
102 while (1) {
103 cmdline = xmlShellReadline("> ");
104 if (cmdline == NULL)
105 return;
106
107 /*
108 * Parse the command itself
109 */
110 cur = cmdline;
111 nbargs = 0;
112 while ((*cur == ' ') || (*cur == '\t')) cur++;
113 i = 0;
114 while ((*cur != ' ') && (*cur != '\t') &&
115 (*cur != '\n') && (*cur != '\r')) {
116 if (*cur == 0)
117 break;
118 command[i++] = *cur++;
119 }
120 command[i] = 0;
121 if (i == 0) {
122 free(cmdline);
123 continue;
124 }
125
126 /*
127 * Parse the argument string
128 */
129 memset(arg, 0, sizeof(arg));
130 while ((*cur == ' ') || (*cur == '\t')) cur++;
131 i = 0;
132 while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
133 if (*cur == 0)
134 break;
135 arg[i++] = *cur++;
136 }
137 arg[i] = 0;
138
139 /*
140 * Parse the arguments
141 */
142 i = 0;
143 nbargs = 0;
144 cur = arg;
145 memset(argv, 0, sizeof(argv));
146 while (*cur != 0) {
147 while ((*cur == ' ') || (*cur == '\t')) cur++;
148 if (*cur == '\'') {
149 cur++;
150 argv[i] = cur;
151 while ((*cur != 0) && (*cur != '\'')) cur++;
152 if (*cur == '\'') {
153 *cur = 0;
154 nbargs++;
155 i++;
156 cur++;
157 }
158 } else if (*cur == '"') {
159 cur++;
160 argv[i] = cur;
161 while ((*cur != 0) && (*cur != '"')) cur++;
162 if (*cur == '"') {
163 *cur = 0;
164 nbargs++;
165 i++;
166 cur++;
167 }
168 } else {
169 argv[i] = cur;
170 while ((*cur != 0) && (*cur != ' ') && (*cur != '\t'))
171 cur++;
172 *cur = 0;
173 nbargs++;
174 i++;
175 cur++;
176 }
177 }
178
179 /*
180 * start interpreting the command
181 */
182 if (!strcmp(command, "exit") ||
183 !strcmp(command, "quit") ||
184 !strcmp(command, "bye")) {
185 free(cmdline);
186 break;
187 }
188
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", (char *) 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", (char *) ans);
210 xmlFree(ans);
211 }
212 }
213 } else if (!strcmp(command, "add")) {
214 if ((nbargs != 3) && (nbargs != 2)) {
215 printf("add requires 2 or 3 arguments\n");
216 } else {
217 if (argv[2] == NULL)
218 ret = xmlCatalogAdd(BAD_CAST argv[0], NULL,
219 BAD_CAST argv[1]);
220 else
221 ret = xmlCatalogAdd(BAD_CAST argv[0], BAD_CAST argv[1],
222 BAD_CAST argv[2]);
223 if (ret != 0)
224 printf("add command failed\n");
225 }
226 } else if (!strcmp(command, "del")) {
227 if (nbargs != 1) {
228 printf("del requires 1\n");
229 } else {
230 ret = xmlCatalogRemove(BAD_CAST argv[0]);
231 if (ret <= 0)
232 printf("del command failed\n");
233
234 }
235 } else if (!strcmp(command, "resolve")) {
236 if (nbargs != 2) {
237 printf("resolve requires 2 arguments\n");
238 } else {
239 ans = xmlCatalogResolve(BAD_CAST argv[0],
240 BAD_CAST argv[1]);
241 if (ans == NULL) {
242 printf("Resolver failed to find an answer\n");
243 } else {
244 printf("%s\n", (char *) ans);
245 xmlFree(ans);
246 }
247 }
248 } else if (!strcmp(command, "dump")) {
249 if (nbargs != 0) {
250 printf("dump has no arguments\n");
251 } else {
252 xmlCatalogDump(stdout);
253 }
254 } else if (!strcmp(command, "debug")) {
255 if (nbargs != 0) {
256 printf("debug has no arguments\n");
257 } else {
258 verbose++;
259 xmlCatalogSetDebug(verbose);
260 }
261 } else if (!strcmp(command, "quiet")) {
262 if (nbargs != 0) {
263 printf("quiet has no arguments\n");
264 } else {
265 if (verbose > 0)
266 verbose--;
267 xmlCatalogSetDebug(verbose);
268 }
269 } else {
270 if (strcmp(command, "help")) {
271 printf("Unrecognized command %s\n", command);
272 }
273 printf("Commands available:\n");
274 printf("\tpublic PublicID: make a PUBLIC identifier lookup\n");
275 printf("\tsystem SystemID: make a SYSTEM identifier lookup\n");
276 printf("\tresolve PublicID SystemID: do a full resolver lookup\n");
277 printf("\tadd 'type' 'orig' 'replace' : add an entry\n");
278 printf("\tdel 'values' : remove values\n");
279 printf("\tdump: print the current catalog state\n");
280 printf("\tdebug: increase the verbosity level\n");
281 printf("\tquiet: decrease the verbosity level\n");
282 printf("\texit: quit the shell\n");
283 }
284 free(cmdline); /* not xmlFree here ! */
285 }
286}
287
288/************************************************************************
289 * *
290 * Main *
291 * *
292 ************************************************************************/
293static void usage(const char *name) {
294 /* split into 2 printf's to avoid overly long string (gcc warning) */
295 printf("\
296Usage : %s [options] catalogfile entities...\n\
297\tParse the catalog file (void specification possibly expressed as \"\"\n\
298\tappoints the default system one) and query it for the entities\n\
299\t--sgml : handle SGML Super catalogs for --add and --del\n\
300\t--shell : run a shell allowing interactive queries\n\
301\t--create : create a new catalog\n\
302\t--add 'type' 'orig' 'replace' : add an XML entry\n\
303\t--add 'entry' : add an SGML entry\n", name);
304 printf("\
305\t--del 'values' : remove values\n\
306\t--noout: avoid dumping the result on stdout\n\
307\t used with --add or --del, it saves the catalog changes\n\
308\t and with --sgml it automatically updates the super catalog\n\
309\t--no-super-update: do not update the SGML super catalog\n\
310\t-v --verbose : provide debug information\n");
311}
312int main(int argc, char **argv) {
313 int i;
314 int ret;
315 int exit_value = 0;
316
317
318 if (argc <= 1) {
319 usage(argv[0]);
320 return(1);
321 }
322
324 for (i = 1; i < argc ; i++) {
325 if (!strcmp(argv[i], "-"))
326 break;
327
328 if (argv[i][0] != '-')
329 break;
330 if ((!strcmp(argv[i], "-verbose")) ||
331 (!strcmp(argv[i], "-v")) ||
332 (!strcmp(argv[i], "--verbose"))) {
333 verbose++;
334 xmlCatalogSetDebug(verbose);
335 } else if ((!strcmp(argv[i], "-noout")) ||
336 (!strcmp(argv[i], "--noout"))) {
337 noout = 1;
338 } else if ((!strcmp(argv[i], "-shell")) ||
339 (!strcmp(argv[i], "--shell"))) {
340 shell++;
341 noout = 1;
342 } else if ((!strcmp(argv[i], "-sgml")) ||
343 (!strcmp(argv[i], "--sgml"))) {
344 sgml++;
345 } else if ((!strcmp(argv[i], "-create")) ||
346 (!strcmp(argv[i], "--create"))) {
347 create++;
348 } else if ((!strcmp(argv[i], "-convert")) ||
349 (!strcmp(argv[i], "--convert"))) {
350 convert++;
351 } else if ((!strcmp(argv[i], "-no-super-update")) ||
352 (!strcmp(argv[i], "--no-super-update"))) {
353 no_super_update++;
354 } else if ((!strcmp(argv[i], "-add")) ||
355 (!strcmp(argv[i], "--add"))) {
356 if (sgml)
357 i += 2;
358 else
359 i += 3;
360 add++;
361 } else if ((!strcmp(argv[i], "-del")) ||
362 (!strcmp(argv[i], "--del"))) {
363 i += 1;
364 del++;
365 } else {
366 fprintf(stderr, "Unknown option %s\n", argv[i]);
367 usage(argv[0]);
368 return(1);
369 }
370 }
371
372 for (i = 1; i < argc; i++) {
373 if ((!strcmp(argv[i], "-add")) ||
374 (!strcmp(argv[i], "--add"))) {
375 if (sgml)
376 i += 2;
377 else
378 i += 3;
379 continue;
380 } else if ((!strcmp(argv[i], "-del")) ||
381 (!strcmp(argv[i], "--del"))) {
382 i += 1;
383
384 /* No catalog entry specified */
385 if (i == argc || (sgml && i + 1 == argc)) {
386 fprintf(stderr, "No catalog entry specified to remove from\n");
387 usage (argv[0]);
388 return(1);
389 }
390
391 continue;
392 } else if (argv[i][0] == '-')
393 continue;
394
395 if (filename == NULL && argv[i][0] == '\0') {
396 /* Interpret empty-string catalog specification as
397 a shortcut for a default system catalog. */
398 xmlInitializeCatalog();
399 } else {
400 filename = argv[i];
401 ret = xmlLoadCatalog(argv[i]);
402 if ((ret < 0) && (create)) {
403 xmlCatalogAdd(BAD_CAST "catalog", BAD_CAST argv[i], NULL);
404 }
405 }
406 break;
407 }
408
409 if (convert)
410 ret = xmlCatalogConvert();
411
412 if ((add) || (del)) {
413 for (i = 1; i < argc ; i++) {
414 if (!strcmp(argv[i], "-"))
415 break;
416
417 if (argv[i][0] != '-')
418 continue;
419 if (strcmp(argv[i], "-add") && strcmp(argv[i], "--add") &&
420 strcmp(argv[i], "-del") && strcmp(argv[i], "--del"))
421 continue;
422
423 if (sgml) {
424 /*
425 * Maintenance of SGML catalogs.
426 */
427 xmlCatalogPtr catal = NULL;
428 xmlCatalogPtr super = NULL;
429
430 catal = xmlLoadSGMLSuperCatalog(argv[i + 1]);
431
432 if ((!strcmp(argv[i], "-add")) ||
433 (!strcmp(argv[i], "--add"))) {
434 if (catal == NULL)
435 catal = xmlNewCatalog(1);
436 xmlACatalogAdd(catal, BAD_CAST "CATALOG",
437 BAD_CAST argv[i + 2], NULL);
438
439 if (!no_super_update) {
440 super = xmlLoadSGMLSuperCatalog(XML_SGML_DEFAULT_CATALOG);
441 if (super == NULL)
442 super = xmlNewCatalog(1);
443
444 xmlACatalogAdd(super, BAD_CAST "CATALOG",
445 BAD_CAST argv[i + 1], NULL);
446 }
447 } else {
448 if (catal != NULL)
449 ret = xmlACatalogRemove(catal, BAD_CAST argv[i + 2]);
450 else
451 ret = -1;
452 if (ret < 0) {
453 fprintf(stderr, "Failed to remove entry from %s\n",
454 argv[i + 1]);
455 exit_value = 1;
456 }
457 if ((!no_super_update) && (noout) && (catal != NULL) &&
458 (xmlCatalogIsEmpty(catal))) {
459 super = xmlLoadSGMLSuperCatalog(
460 XML_SGML_DEFAULT_CATALOG);
461 if (super != NULL) {
462 ret = xmlACatalogRemove(super,
463 BAD_CAST argv[i + 1]);
464 if (ret < 0) {
466 "Failed to remove entry from %s\n",
467 XML_SGML_DEFAULT_CATALOG);
468 exit_value = 1;
469 }
470 }
471 }
472 }
473 if (noout) {
474 FILE *out;
475
476 if (xmlCatalogIsEmpty(catal)) {
477 remove(argv[i + 1]);
478 } else {
479 out = fopen(argv[i + 1], "w");
480 if (out == NULL) {
481 fprintf(stderr, "could not open %s for saving\n",
482 argv[i + 1]);
483 exit_value = 2;
484 noout = 0;
485 } else {
486 xmlACatalogDump(catal, out);
487 fclose(out);
488 }
489 }
490 if (!no_super_update && super != NULL) {
491 if (xmlCatalogIsEmpty(super)) {
492 remove(XML_SGML_DEFAULT_CATALOG);
493 } else {
494 out = fopen(XML_SGML_DEFAULT_CATALOG, "w");
495 if (out == NULL) {
497 "could not open %s for saving\n",
498 XML_SGML_DEFAULT_CATALOG);
499 exit_value = 2;
500 noout = 0;
501 } else {
502
503 xmlACatalogDump(super, out);
504 fclose(out);
505 }
506 }
507 }
508 } else {
509 xmlACatalogDump(catal, stdout);
510 }
511 i += 2;
512 } else {
513 if ((!strcmp(argv[i], "-add")) ||
514 (!strcmp(argv[i], "--add"))) {
515 if ((argv[i + 3] == NULL) || (argv[i + 3][0] == 0))
516 ret = xmlCatalogAdd(BAD_CAST argv[i + 1], NULL,
517 BAD_CAST argv[i + 2]);
518 else
519 ret = xmlCatalogAdd(BAD_CAST argv[i + 1],
520 BAD_CAST argv[i + 2],
521 BAD_CAST argv[i + 3]);
522 if (ret != 0) {
523 printf("add command failed\n");
524 exit_value = 3;
525 }
526 i += 3;
527 } else if ((!strcmp(argv[i], "-del")) ||
528 (!strcmp(argv[i], "--del"))) {
529 ret = xmlCatalogRemove(BAD_CAST argv[i + 1]);
530 if (ret < 0) {
531 fprintf(stderr, "Failed to remove entry %s\n",
532 argv[i + 1]);
533 exit_value = 1;
534 }
535 i += 1;
536 }
537 }
538 }
539
540 } else if (shell) {
541 usershell();
542 } else {
543 for (i++; i < argc; i++) {
545 xmlChar *ans;
546
547 uri = xmlParseURI(argv[i]);
548 if (uri == NULL) {
549 ans = xmlCatalogResolvePublic((const xmlChar *) argv[i]);
550 if (ans == NULL) {
551 printf("No entry for PUBLIC %s\n", argv[i]);
552 exit_value = 4;
553 } else {
554 printf("%s\n", (char *) ans);
555 xmlFree(ans);
556 }
557 } else {
559 ans = xmlCatalogResolveSystem((const xmlChar *) argv[i]);
560 if (ans == NULL) {
561 printf("No entry for SYSTEM %s\n", argv[i]);
562 ans = xmlCatalogResolveURI ((const xmlChar *) argv[i]);
563 if (ans == NULL) {
564 printf ("No entry for URI %s\n", argv[i]);
565 exit_value = 4;
566 } else {
567 printf("%s\n", (char *) ans);
568 xmlFree (ans);
569 }
570 } else {
571 printf("%s\n", (char *) ans);
572 xmlFree(ans);
573 }
574 }
575 }
576 }
577 if ((!sgml) && ((add) || (del) || (create) || (convert))) {
578 if (noout && filename && *filename) {
579 FILE *out;
580
581 out = fopen(filename, "w");
582 if (out == NULL) {
583 fprintf(stderr, "could not open %s for saving\n", filename);
584 exit_value = 2;
585 noout = 0;
586 } else {
587 xmlCatalogDump(out);
588 }
589 } else {
590 xmlCatalogDump(stdout);
591 }
592 }
593
594 /*
595 * Cleanup and check for memory leaks
596 */
599 return(exit_value);
600}
601#else
603 fprintf(stderr, "libxml was not compiled with catalog and output support\n");
604 return(1);
605}
606#endif
static int argc
Definition: ServiceArgs.c:12
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static logline * readline(FILE *inf, adns_state adns, int opts)
Definition: adnslogres.c:145
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
static VOID del(LPHIST_ENTRY item)
Definition: history.c:199
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
int main()
Definition: test.c:6
#define printf
Definition: freeldr.h:97
FxCollectionEntry * cur
GLenum GLsizei len
Definition: glext.h:6722
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ATTRIBUTE_UNUSED
Definition: i386-dis.c:36
#define stdout
Definition: stdio.h:99
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define stdin
Definition: stdio.h:98
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
const char * filename
Definition: ioapi.h:137
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static const struct access_res create[16]
Definition: package.c:7505
const char * uri
Definition: sec_mgr.c:1588
#define argv
Definition: mplay32.c:18
int convert
Definition: msacm.c:1374
int remove
Definition: msacm.c:1366
static FILE * out
Definition: regtests2xml.c:44
#define verbose
Definition: rosglue.h:36
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBFUN void XMLCALL xmlCleanupParser(void)
Definition: parser.c:14739
#define memset(x, y, z)
Definition: compat.h:39
TCHAR * cmdline
Definition: stretchblt.cpp:32
Definition: uri.h:33
Definition: name.c:39
XMLPUBFUN xmlURIPtr XMLCALL xmlParseURI(const char *str)
Definition: uri.c:940
XMLPUBFUN void XMLCALL xmlFreeURI(xmlURIPtr uri)
Definition: uri.c:1387
int ret
void * arg
Definition: msvc.h:10
static int noout
Definition: xmllint.c:113
XMLPUBFUN void XMLCALL xmlMemoryDump(void)
Definition: xmlmemory.c:910
#define BAD_CAST
Definition: xmlstring.h:35
unsigned char xmlChar
Definition: xmlstring.h:28
#define LIBXML_TEST_VERSION
Definition: xmlversion.h:61