Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxmlcatalog.c
Go to the documentation of this file.
00001 /* 00002 * xmlcatalog.c : a small utility program to handle XML catalogs 00003 * 00004 * See Copyright for the status of this software. 00005 * 00006 * daniel@veillard.com 00007 */ 00008 00009 #include "libxml.h" 00010 00011 #include <string.h> 00012 #include <stdio.h> 00013 #include <stdarg.h> 00014 00015 #ifdef HAVE_STDLIB_H 00016 #include <stdlib.h> 00017 #endif 00018 00019 #ifdef HAVE_LIBREADLINE 00020 #include <readline/readline.h> 00021 #ifdef HAVE_LIBHISTORY 00022 #include <readline/history.h> 00023 #endif 00024 #endif 00025 00026 #include <libxml/xmlmemory.h> 00027 #include <libxml/uri.h> 00028 #include <libxml/catalog.h> 00029 #include <libxml/parser.h> 00030 #include <libxml/globals.h> 00031 00032 #if defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_OUTPUT_ENABLED) 00033 static int shell = 0; 00034 static int sgml = 0; 00035 static int noout = 0; 00036 static int create = 0; 00037 static int add = 0; 00038 static int del = 0; 00039 static int convert = 0; 00040 static int no_super_update = 0; 00041 static int verbose = 0; 00042 static char *filename = NULL; 00043 00044 00045 #ifndef XML_SGML_DEFAULT_CATALOG 00046 #define XML_SGML_DEFAULT_CATALOG "/etc/sgml/catalog" 00047 #endif 00048 00049 /************************************************************************ 00050 * * 00051 * Shell Interface * 00052 * * 00053 ************************************************************************/ 00063 static char * 00064 xmlShellReadline(const char *prompt) { 00065 #ifdef HAVE_LIBREADLINE 00066 char *line_read; 00067 00068 /* Get a line from the user. */ 00069 line_read = readline (prompt); 00070 00071 /* If the line has any text in it, save it on the history. */ 00072 if (line_read && *line_read) 00073 add_history (line_read); 00074 00075 return (line_read); 00076 #else 00077 char line_read[501]; 00078 char *ret; 00079 int len; 00080 00081 if (prompt != NULL) 00082 fprintf(stdout, "%s", prompt); 00083 if (!fgets(line_read, 500, stdin)) 00084 return(NULL); 00085 line_read[500] = 0; 00086 len = strlen(line_read); 00087 ret = (char *) malloc(len + 1); 00088 if (ret != NULL) { 00089 memcpy (ret, line_read, len + 1); 00090 } 00091 return(ret); 00092 #endif 00093 } 00094 00095 static void usershell(void) { 00096 char *cmdline = NULL, *cur; 00097 int nbargs; 00098 char command[100]; 00099 char arg[400]; 00100 char *argv[20]; 00101 int i, ret; 00102 xmlChar *ans; 00103 00104 while (1) { 00105 cmdline = xmlShellReadline("> "); 00106 if (cmdline == NULL) 00107 return; 00108 00109 /* 00110 * Parse the command itself 00111 */ 00112 cur = cmdline; 00113 nbargs = 0; 00114 while ((*cur == ' ') || (*cur == '\t')) cur++; 00115 i = 0; 00116 while ((*cur != ' ') && (*cur != '\t') && 00117 (*cur != '\n') && (*cur != '\r')) { 00118 if (*cur == 0) 00119 break; 00120 command[i++] = *cur++; 00121 } 00122 command[i] = 0; 00123 if (i == 0) { 00124 free(cmdline); 00125 continue; 00126 } 00127 00128 /* 00129 * Parse the argument string 00130 */ 00131 memset(arg, 0, sizeof(arg)); 00132 while ((*cur == ' ') || (*cur == '\t')) cur++; 00133 i = 0; 00134 while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) { 00135 if (*cur == 0) 00136 break; 00137 arg[i++] = *cur++; 00138 } 00139 arg[i] = 0; 00140 00141 /* 00142 * Parse the arguments 00143 */ 00144 i = 0; 00145 nbargs = 0; 00146 cur = arg; 00147 memset(argv, 0, sizeof(argv)); 00148 while (*cur != 0) { 00149 while ((*cur == ' ') || (*cur == '\t')) cur++; 00150 if (*cur == '\'') { 00151 cur++; 00152 argv[i] = cur; 00153 while ((*cur != 0) && (*cur != '\'')) cur++; 00154 if (*cur == '\'') { 00155 *cur = 0; 00156 nbargs++; 00157 i++; 00158 cur++; 00159 } 00160 } else if (*cur == '"') { 00161 cur++; 00162 argv[i] = cur; 00163 while ((*cur != 0) && (*cur != '"')) cur++; 00164 if (*cur == '"') { 00165 *cur = 0; 00166 nbargs++; 00167 i++; 00168 cur++; 00169 } 00170 } else { 00171 argv[i] = cur; 00172 while ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) 00173 cur++; 00174 *cur = 0; 00175 nbargs++; 00176 i++; 00177 cur++; 00178 } 00179 } 00180 00181 /* 00182 * start interpreting the command 00183 */ 00184 if (!strcmp(command, "exit")) 00185 break; 00186 if (!strcmp(command, "quit")) 00187 break; 00188 if (!strcmp(command, "bye")) 00189 break; 00190 if (!strcmp(command, "public")) { 00191 if (nbargs != 1) { 00192 printf("public requires 1 arguments\n"); 00193 } else { 00194 ans = xmlCatalogResolvePublic((const xmlChar *) argv[0]); 00195 if (ans == NULL) { 00196 printf("No entry for PUBLIC %s\n", argv[0]); 00197 } else { 00198 printf("%s\n", (char *) ans); 00199 xmlFree(ans); 00200 } 00201 } 00202 } else if (!strcmp(command, "system")) { 00203 if (nbargs != 1) { 00204 printf("system requires 1 arguments\n"); 00205 } else { 00206 ans = xmlCatalogResolveSystem((const xmlChar *) argv[0]); 00207 if (ans == NULL) { 00208 printf("No entry for SYSTEM %s\n", argv[0]); 00209 } else { 00210 printf("%s\n", (char *) ans); 00211 xmlFree(ans); 00212 } 00213 } 00214 } else if (!strcmp(command, "add")) { 00215 if (sgml) { 00216 if ((nbargs != 3) && (nbargs != 2)) { 00217 printf("add requires 2 or 3 arguments\n"); 00218 } else { 00219 if (argv[2] == NULL) 00220 ret = xmlCatalogAdd(BAD_CAST argv[0], NULL, 00221 BAD_CAST argv[1]); 00222 else 00223 ret = xmlCatalogAdd(BAD_CAST argv[0], BAD_CAST argv[1], 00224 BAD_CAST argv[2]); 00225 if (ret != 0) 00226 printf("add command failed\n"); 00227 } 00228 } else { 00229 if ((nbargs != 3) && (nbargs != 2)) { 00230 printf("add requires 2 or 3 arguments\n"); 00231 } else { 00232 if (argv[2] == NULL) 00233 ret = xmlCatalogAdd(BAD_CAST argv[0], NULL, 00234 BAD_CAST argv[1]); 00235 else 00236 ret = xmlCatalogAdd(BAD_CAST argv[0], BAD_CAST argv[1], 00237 BAD_CAST argv[2]); 00238 if (ret != 0) 00239 printf("add command failed\n"); 00240 } 00241 } 00242 } else if (!strcmp(command, "del")) { 00243 if (nbargs != 1) { 00244 printf("del requires 1\n"); 00245 } else { 00246 ret = xmlCatalogRemove(BAD_CAST argv[0]); 00247 if (ret <= 0) 00248 printf("del command failed\n"); 00249 00250 } 00251 } else if (!strcmp(command, "resolve")) { 00252 if (nbargs != 2) { 00253 printf("resolve requires 2 arguments\n"); 00254 } else { 00255 ans = xmlCatalogResolve(BAD_CAST argv[0], 00256 BAD_CAST argv[1]); 00257 if (ans == NULL) { 00258 printf("Resolver failed to find an answer\n"); 00259 } else { 00260 printf("%s\n", (char *) ans); 00261 xmlFree(ans); 00262 } 00263 } 00264 } else if (!strcmp(command, "dump")) { 00265 if (nbargs != 0) { 00266 printf("dump has no arguments\n"); 00267 } else { 00268 xmlCatalogDump(stdout); 00269 } 00270 } else if (!strcmp(command, "debug")) { 00271 if (nbargs != 0) { 00272 printf("debug has no arguments\n"); 00273 } else { 00274 verbose++; 00275 xmlCatalogSetDebug(verbose); 00276 } 00277 } else if (!strcmp(command, "quiet")) { 00278 if (nbargs != 0) { 00279 printf("quiet has no arguments\n"); 00280 } else { 00281 if (verbose > 0) 00282 verbose--; 00283 xmlCatalogSetDebug(verbose); 00284 } 00285 } else { 00286 if (strcmp(command, "help")) { 00287 printf("Unrecognized command %s\n", command); 00288 } 00289 printf("Commands available:\n"); 00290 printf("\tpublic PublicID: make a PUBLIC identifier lookup\n"); 00291 printf("\tsystem SystemID: make a SYSTEM identifier lookup\n"); 00292 printf("\tresolve PublicID SystemID: do a full resolver lookup\n"); 00293 printf("\tadd 'type' 'orig' 'replace' : add an entry\n"); 00294 printf("\tdel 'values' : remove values\n"); 00295 printf("\tdump: print the current catalog state\n"); 00296 printf("\tdebug: increase the verbosity level\n"); 00297 printf("\tquiet: decrease the verbosity level\n"); 00298 printf("\texit: quit the shell\n"); 00299 } 00300 free(cmdline); /* not xmlFree here ! */ 00301 } 00302 } 00303 00304 /************************************************************************ 00305 * * 00306 * Main * 00307 * * 00308 ************************************************************************/ 00309 static void usage(const char *name) { 00310 /* split into 2 printf's to avoid overly long string (gcc warning) */ 00311 printf("\ 00312 Usage : %s [options] catalogfile entities...\n\ 00313 \tParse the catalog file and query it for the entities\n\ 00314 \t--sgml : handle SGML Super catalogs for --add and --del\n\ 00315 \t--shell : run a shell allowing interactive queries\n\ 00316 \t--create : create a new catalog\n\ 00317 \t--add 'type' 'orig' 'replace' : add an XML entry\n\ 00318 \t--add 'entry' : add an SGML entry\n", name); 00319 printf("\ 00320 \t--del 'values' : remove values\n\ 00321 \t--noout: avoid dumping the result on stdout\n\ 00322 \t used with --add or --del, it saves the catalog changes\n\ 00323 \t and with --sgml it automatically updates the super catalog\n\ 00324 \t--no-super-update: do not update the SGML super catalog\n\ 00325 \t-v --verbose : provide debug informations\n"); 00326 } 00327 int main(int argc, char **argv) { 00328 int i; 00329 int ret; 00330 int exit_value = 0; 00331 00332 00333 if (argc <= 1) { 00334 usage(argv[0]); 00335 return(1); 00336 } 00337 00338 LIBXML_TEST_VERSION 00339 for (i = 1; i < argc ; i++) { 00340 if (!strcmp(argv[i], "-")) 00341 break; 00342 00343 if (argv[i][0] != '-') 00344 break; 00345 if ((!strcmp(argv[i], "-verbose")) || 00346 (!strcmp(argv[i], "-v")) || 00347 (!strcmp(argv[i], "--verbose"))) { 00348 verbose++; 00349 xmlCatalogSetDebug(verbose); 00350 } else if ((!strcmp(argv[i], "-noout")) || 00351 (!strcmp(argv[i], "--noout"))) { 00352 noout = 1; 00353 } else if ((!strcmp(argv[i], "-shell")) || 00354 (!strcmp(argv[i], "--shell"))) { 00355 shell++; 00356 noout = 1; 00357 } else if ((!strcmp(argv[i], "-sgml")) || 00358 (!strcmp(argv[i], "--sgml"))) { 00359 sgml++; 00360 } else if ((!strcmp(argv[i], "-create")) || 00361 (!strcmp(argv[i], "--create"))) { 00362 create++; 00363 } else if ((!strcmp(argv[i], "-convert")) || 00364 (!strcmp(argv[i], "--convert"))) { 00365 convert++; 00366 } else if ((!strcmp(argv[i], "-no-super-update")) || 00367 (!strcmp(argv[i], "--no-super-update"))) { 00368 no_super_update++; 00369 } else if ((!strcmp(argv[i], "-add")) || 00370 (!strcmp(argv[i], "--add"))) { 00371 if (sgml) 00372 i += 2; 00373 else 00374 i += 3; 00375 add++; 00376 } else if ((!strcmp(argv[i], "-del")) || 00377 (!strcmp(argv[i], "--del"))) { 00378 i += 1; 00379 del++; 00380 } else { 00381 fprintf(stderr, "Unknown option %s\n", argv[i]); 00382 usage(argv[0]); 00383 return(1); 00384 } 00385 } 00386 00387 for (i = 1; i < argc; i++) { 00388 if ((!strcmp(argv[i], "-add")) || 00389 (!strcmp(argv[i], "--add"))) { 00390 if (sgml) 00391 i += 2; 00392 else 00393 i += 3; 00394 continue; 00395 } else if ((!strcmp(argv[i], "-del")) || 00396 (!strcmp(argv[i], "--del"))) { 00397 i += 1; 00398 00399 /* No catalog entry specified */ 00400 if (i == argc || (sgml && i + 1 == argc)) { 00401 fprintf(stderr, "No catalog entry specified to remove from\n"); 00402 usage (argv[0]); 00403 return(1); 00404 } 00405 00406 continue; 00407 } else if (argv[i][0] == '-') 00408 continue; 00409 filename = argv[i]; 00410 ret = xmlLoadCatalog(argv[i]); 00411 if ((ret < 0) && (create)) { 00412 xmlCatalogAdd(BAD_CAST "catalog", BAD_CAST argv[i], NULL); 00413 } 00414 break; 00415 } 00416 00417 if (convert) 00418 ret = xmlCatalogConvert(); 00419 00420 if ((add) || (del)) { 00421 for (i = 1; i < argc ; i++) { 00422 if (!strcmp(argv[i], "-")) 00423 break; 00424 00425 if (argv[i][0] != '-') 00426 continue; 00427 if (strcmp(argv[i], "-add") && strcmp(argv[i], "--add") && 00428 strcmp(argv[i], "-del") && strcmp(argv[i], "--del")) 00429 continue; 00430 00431 if (sgml) { 00432 /* 00433 * Maintenance of SGML catalogs. 00434 */ 00435 xmlCatalogPtr catal = NULL; 00436 xmlCatalogPtr super = NULL; 00437 00438 catal = xmlLoadSGMLSuperCatalog(argv[i + 1]); 00439 00440 if ((!strcmp(argv[i], "-add")) || 00441 (!strcmp(argv[i], "--add"))) { 00442 if (catal == NULL) 00443 catal = xmlNewCatalog(1); 00444 xmlACatalogAdd(catal, BAD_CAST "CATALOG", 00445 BAD_CAST argv[i + 2], NULL); 00446 00447 if (!no_super_update) { 00448 super = xmlLoadSGMLSuperCatalog(XML_SGML_DEFAULT_CATALOG); 00449 if (super == NULL) 00450 super = xmlNewCatalog(1); 00451 00452 xmlACatalogAdd(super, BAD_CAST "CATALOG", 00453 BAD_CAST argv[i + 1], NULL); 00454 } 00455 } else { 00456 if (catal != NULL) 00457 ret = xmlACatalogRemove(catal, BAD_CAST argv[i + 2]); 00458 else 00459 ret = -1; 00460 if (ret < 0) { 00461 fprintf(stderr, "Failed to remove entry from %s\n", 00462 argv[i + 1]); 00463 exit_value = 1; 00464 } 00465 if ((!no_super_update) && (noout) && (catal != NULL) && 00466 (xmlCatalogIsEmpty(catal))) { 00467 super = xmlLoadSGMLSuperCatalog( 00468 XML_SGML_DEFAULT_CATALOG); 00469 if (super != NULL) { 00470 ret = xmlACatalogRemove(super, 00471 BAD_CAST argv[i + 1]); 00472 if (ret < 0) { 00473 fprintf(stderr, 00474 "Failed to remove entry from %s\n", 00475 XML_SGML_DEFAULT_CATALOG); 00476 exit_value = 1; 00477 } 00478 } 00479 } 00480 } 00481 if (noout) { 00482 FILE *out; 00483 00484 if (xmlCatalogIsEmpty(catal)) { 00485 remove(argv[i + 1]); 00486 } else { 00487 out = fopen(argv[i + 1], "w"); 00488 if (out == NULL) { 00489 fprintf(stderr, "could not open %s for saving\n", 00490 argv[i + 1]); 00491 exit_value = 2; 00492 noout = 0; 00493 } else { 00494 xmlACatalogDump(catal, out); 00495 fclose(out); 00496 } 00497 } 00498 if (!no_super_update && super != NULL) { 00499 if (xmlCatalogIsEmpty(super)) { 00500 remove(XML_SGML_DEFAULT_CATALOG); 00501 } else { 00502 out = fopen(XML_SGML_DEFAULT_CATALOG, "w"); 00503 if (out == NULL) { 00504 fprintf(stderr, 00505 "could not open %s for saving\n", 00506 XML_SGML_DEFAULT_CATALOG); 00507 exit_value = 2; 00508 noout = 0; 00509 } else { 00510 00511 xmlACatalogDump(super, out); 00512 fclose(out); 00513 } 00514 } 00515 } 00516 } else { 00517 xmlACatalogDump(catal, stdout); 00518 } 00519 i += 2; 00520 } else { 00521 if ((!strcmp(argv[i], "-add")) || 00522 (!strcmp(argv[i], "--add"))) { 00523 if ((argv[i + 3] == NULL) || (argv[i + 3][0] == 0)) 00524 ret = xmlCatalogAdd(BAD_CAST argv[i + 1], NULL, 00525 BAD_CAST argv[i + 2]); 00526 else 00527 ret = xmlCatalogAdd(BAD_CAST argv[i + 1], 00528 BAD_CAST argv[i + 2], 00529 BAD_CAST argv[i + 3]); 00530 if (ret != 0) { 00531 printf("add command failed\n"); 00532 exit_value = 3; 00533 } 00534 i += 3; 00535 } else if ((!strcmp(argv[i], "-del")) || 00536 (!strcmp(argv[i], "--del"))) { 00537 ret = xmlCatalogRemove(BAD_CAST argv[i + 1]); 00538 if (ret < 0) { 00539 fprintf(stderr, "Failed to remove entry %s\n", 00540 argv[i + 1]); 00541 exit_value = 1; 00542 } 00543 i += 1; 00544 } 00545 } 00546 } 00547 00548 } else if (shell) { 00549 usershell(); 00550 } else { 00551 for (i++; i < argc; i++) { 00552 xmlURIPtr uri; 00553 xmlChar *ans; 00554 00555 uri = xmlParseURI(argv[i]); 00556 if (uri == NULL) { 00557 ans = xmlCatalogResolvePublic((const xmlChar *) argv[i]); 00558 if (ans == NULL) { 00559 printf("No entry for PUBLIC %s\n", argv[i]); 00560 exit_value = 4; 00561 } else { 00562 printf("%s\n", (char *) ans); 00563 xmlFree(ans); 00564 } 00565 } else { 00566 xmlFreeURI(uri); 00567 ans = xmlCatalogResolveSystem((const xmlChar *) argv[i]); 00568 if (ans == NULL) { 00569 printf("No entry for SYSTEM %s\n", argv[i]); 00570 ans = xmlCatalogResolveURI ((const xmlChar *) argv[i]); 00571 if (ans == NULL) { 00572 printf ("No entry for URI %s\n", argv[i]); 00573 exit_value = 4; 00574 } else { 00575 printf("%s\n", (char *) ans); 00576 xmlFree (ans); 00577 } 00578 } else { 00579 printf("%s\n", (char *) ans); 00580 xmlFree(ans); 00581 } 00582 } 00583 } 00584 } 00585 if ((!sgml) && ((add) || (del) || (create) || (convert))) { 00586 if (noout && filename && *filename) { 00587 FILE *out; 00588 00589 out = fopen(filename, "w"); 00590 if (out == NULL) { 00591 fprintf(stderr, "could not open %s for saving\n", filename); 00592 exit_value = 2; 00593 noout = 0; 00594 } else { 00595 xmlCatalogDump(out); 00596 } 00597 } else { 00598 xmlCatalogDump(stdout); 00599 } 00600 } 00601 00602 /* 00603 * Cleanup and check for memory leaks 00604 */ 00605 xmlCleanupParser(); 00606 xmlMemoryDump(); 00607 return(exit_value); 00608 } 00609 #else 00610 int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { 00611 fprintf(stderr, "libxml was not compiled with catalog and output support\n"); 00612 return(1); 00613 } 00614 #endif Generated on Mon May 28 2012 04:34:32 for ReactOS by
1.7.6.1
|