ReactOS 0.4.15-dev-8092-ge0ba2f3
catalog.c
Go to the documentation of this file.
1
15#define IN_LIBXML
16#include "libxml.h"
17
18#ifdef LIBXML_CATALOG_ENABLED
19#include <stdlib.h>
20#include <string.h>
21#ifdef HAVE_SYS_TYPES_H
22#include <sys/types.h>
23#endif
24#ifdef HAVE_SYS_STAT_H
25#include <sys/stat.h>
26#endif
27#ifdef HAVE_UNISTD_H
28#include <unistd.h>
29#endif
30#ifdef HAVE_FCNTL_H
31#include <fcntl.h>
32#endif
33#include <libxml/xmlmemory.h>
34#include <libxml/hash.h>
35#include <libxml/uri.h>
37#include <libxml/catalog.h>
38#include <libxml/xmlerror.h>
39#include <libxml/threads.h>
40#include <libxml/globals.h>
41
42#include "buf.h"
43
44#define MAX_DELEGATE 50
45#define MAX_CATAL_DEPTH 50
46
47#ifdef _WIN32
48# define PATH_SEPARATOR ';'
49#else
50# define PATH_SEPARATOR ':'
51#endif
52
63#define TODO \
64 xmlGenericError(xmlGenericErrorContext, \
65 "Unimplemented block at %s:%d\n", \
66 __FILE__, __LINE__);
67
68#define XML_URN_PUBID "urn:publicid:"
69#define XML_CATAL_BREAK ((xmlChar *) -1)
70#ifndef XML_XML_DEFAULT_CATALOG
71#define XML_XML_DEFAULT_CATALOG "file://" SYSCONFDIR "/xml/catalog"
72#endif
73#ifndef XML_SGML_DEFAULT_CATALOG
74#define XML_SGML_DEFAULT_CATALOG "file://" SYSCONFDIR "/sgml/catalog"
75#endif
76
77#if defined(_WIN32) && defined(_MSC_VER)
78#undef XML_XML_DEFAULT_CATALOG
79static char XML_XML_DEFAULT_CATALOG[256] = "file://" SYSCONFDIR "/xml/catalog";
80#if !defined(_WINDOWS_)
81void* __stdcall GetModuleHandleA(const char*);
82unsigned long __stdcall GetModuleFileNameA(void*, char*, unsigned long);
83#endif
84#endif
85
86static xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID);
87static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename);
88
89/************************************************************************
90 * *
91 * Types, all private *
92 * *
93 ************************************************************************/
94
95typedef enum {
96 XML_CATA_REMOVED = -1,
97 XML_CATA_NONE = 0,
98 XML_CATA_CATALOG,
99 XML_CATA_BROKEN_CATALOG,
100 XML_CATA_NEXT_CATALOG,
101 XML_CATA_GROUP,
102 XML_CATA_PUBLIC,
103 XML_CATA_SYSTEM,
104 XML_CATA_REWRITE_SYSTEM,
105 XML_CATA_DELEGATE_PUBLIC,
106 XML_CATA_DELEGATE_SYSTEM,
107 XML_CATA_URI,
108 XML_CATA_REWRITE_URI,
109 XML_CATA_DELEGATE_URI,
110 SGML_CATA_SYSTEM,
111 SGML_CATA_PUBLIC,
112 SGML_CATA_ENTITY,
113 SGML_CATA_PENTITY,
114 SGML_CATA_DOCTYPE,
115 SGML_CATA_LINKTYPE,
116 SGML_CATA_NOTATION,
117 SGML_CATA_DELEGATE,
118 SGML_CATA_BASE,
119 SGML_CATA_CATALOG,
120 SGML_CATA_DOCUMENT,
121 SGML_CATA_SGMLDECL
122} xmlCatalogEntryType;
123
124typedef struct _xmlCatalogEntry xmlCatalogEntry;
125typedef xmlCatalogEntry *xmlCatalogEntryPtr;
126struct _xmlCatalogEntry {
127 struct _xmlCatalogEntry *next;
128 struct _xmlCatalogEntry *parent;
129 struct _xmlCatalogEntry *children;
130 xmlCatalogEntryType type;
131 xmlChar *name;
132 xmlChar *value;
133 xmlChar *URL; /* The expanded URL using the base */
134 xmlCatalogPrefer prefer;
135 int dealloc;
136 int depth;
137 struct _xmlCatalogEntry *group;
138};
139
140typedef enum {
141 XML_XML_CATALOG_TYPE = 1,
142 XML_SGML_CATALOG_TYPE
143} xmlCatalogType;
144
145#define XML_MAX_SGML_CATA_DEPTH 10
146struct _xmlCatalog {
147 xmlCatalogType type; /* either XML or SGML */
148
149 /*
150 * SGML Catalogs are stored as a simple hash table of catalog entries
151 * Catalog stack to check against overflows when building the
152 * SGML catalog
153 */
154 char *catalTab[XML_MAX_SGML_CATA_DEPTH]; /* stack of catals */
155 int catalNr; /* Number of current catal streams */
156 int catalMax; /* Max number of catal streams */
157 xmlHashTablePtr sgml;
158
159 /*
160 * XML Catalogs are stored as a tree of Catalog entries
161 */
162 xmlCatalogPrefer prefer;
163 xmlCatalogEntryPtr xml;
164};
165
166/************************************************************************
167 * *
168 * Global variables *
169 * *
170 ************************************************************************/
171
172/*
173 * Those are preferences
174 */
175static int xmlDebugCatalogs = 0; /* used for debugging */
176static xmlCatalogAllow xmlCatalogDefaultAllow = XML_CATA_ALLOW_ALL;
177static xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_PUBLIC;
178
179/*
180 * Hash table containing all the trees of XML catalogs parsed by
181 * the application.
182 */
183static xmlHashTablePtr xmlCatalogXMLFiles = NULL;
184
185/*
186 * The default catalog in use by the application
187 */
188static xmlCatalogPtr xmlDefaultCatalog = NULL;
189
190/*
191 * A mutex for modifying the shared global catalog(s)
192 * xmlDefaultCatalog tree.
193 * It also protects xmlCatalogXMLFiles
194 * The core of this readers/writer scheme is in xmlFetchXMLCatalogFile()
195 */
196static xmlRMutexPtr xmlCatalogMutex = NULL;
197
198/*
199 * Whether the catalog support was initialized.
200 */
201static int xmlCatalogInitialized = 0;
202
203/************************************************************************
204 * *
205 * Catalog error handlers *
206 * *
207 ************************************************************************/
208
215static void
216xmlCatalogErrMemory(const char *extra)
217{
218 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_CATALOG,
220 extra, NULL, NULL, 0, 0,
221 "Memory allocation failed : %s\n", extra);
222}
223
233static void LIBXML_ATTR_FORMAT(4,0)
234xmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error,
235 const char *msg, const xmlChar *str1, const xmlChar *str2,
236 const xmlChar *str3)
237{
238 __xmlRaiseError(NULL, NULL, NULL, catal, node, XML_FROM_CATALOG,
240 (const char *) str1, (const char *) str2,
241 (const char *) str3, 0, 0,
242 msg, str1, str2, str3);
243}
244
245
246/************************************************************************
247 * *
248 * Allocation and Freeing *
249 * *
250 ************************************************************************/
251
265static xmlCatalogEntryPtr
266xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
267 const xmlChar *value, const xmlChar *URL, xmlCatalogPrefer prefer,
268 xmlCatalogEntryPtr group) {
269 xmlCatalogEntryPtr ret;
270 xmlChar *normid = NULL;
271
272 ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
273 if (ret == NULL) {
274 xmlCatalogErrMemory("allocating catalog entry");
275 return(NULL);
276 }
277 ret->next = NULL;
278 ret->parent = NULL;
279 ret->children = NULL;
280 ret->type = type;
281 if (type == XML_CATA_PUBLIC || type == XML_CATA_DELEGATE_PUBLIC) {
282 normid = xmlCatalogNormalizePublic(name);
283 if (normid != NULL)
284 name = (*normid != 0 ? normid : NULL);
285 }
286 if (name != NULL)
287 ret->name = xmlStrdup(name);
288 else
289 ret->name = NULL;
290 if (normid != NULL)
291 xmlFree(normid);
292 if (value != NULL)
293 ret->value = xmlStrdup(value);
294 else
295 ret->value = NULL;
296 if (URL == NULL)
297 URL = value;
298 if (URL != NULL)
299 ret->URL = xmlStrdup(URL);
300 else
301 ret->URL = NULL;
302 ret->prefer = prefer;
303 ret->dealloc = 0;
304 ret->depth = 0;
305 ret->group = group;
306 return(ret);
307}
308
309static void
310xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret);
311
318static void
319xmlFreeCatalogEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
320 xmlCatalogEntryPtr ret = (xmlCatalogEntryPtr) payload;
321 if (ret == NULL)
322 return;
323 /*
324 * Entries stored in the file hash must be deallocated
325 * only by the file hash cleaner !
326 */
327 if (ret->dealloc == 1)
328 return;
329
330 if (xmlDebugCatalogs) {
331 if (ret->name != NULL)
333 "Free catalog entry %s\n", ret->name);
334 else if (ret->value != NULL)
336 "Free catalog entry %s\n", ret->value);
337 else
339 "Free catalog entry\n");
340 }
341
342 if (ret->name != NULL)
343 xmlFree(ret->name);
344 if (ret->value != NULL)
345 xmlFree(ret->value);
346 if (ret->URL != NULL)
347 xmlFree(ret->URL);
348 xmlFree(ret);
349}
350
357static void
358xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret) {
359 xmlCatalogEntryPtr next;
360
361 while (ret != NULL) {
362 next = ret->next;
363 xmlFreeCatalogEntry(ret, NULL);
364 ret = next;
365 }
366}
367
375static void
376xmlFreeCatalogHashEntryList(void *payload,
378 xmlCatalogEntryPtr catal = (xmlCatalogEntryPtr) payload;
379 xmlCatalogEntryPtr children, next;
380
381 if (catal == NULL)
382 return;
383
384 children = catal->children;
385 while (children != NULL) {
386 next = children->next;
387 children->dealloc = 0;
388 children->children = NULL;
389 xmlFreeCatalogEntry(children, NULL);
390 children = next;
391 }
392 catal->dealloc = 0;
393 xmlFreeCatalogEntry(catal, NULL);
394}
395
406static xmlCatalogPtr
407xmlCreateNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) {
408 xmlCatalogPtr ret;
409
410 ret = (xmlCatalogPtr) xmlMalloc(sizeof(xmlCatalog));
411 if (ret == NULL) {
412 xmlCatalogErrMemory("allocating catalog");
413 return(NULL);
414 }
415 memset(ret, 0, sizeof(xmlCatalog));
416 ret->type = type;
417 ret->catalNr = 0;
418 ret->catalMax = XML_MAX_SGML_CATA_DEPTH;
419 ret->prefer = prefer;
420 if (ret->type == XML_SGML_CATALOG_TYPE)
421 ret->sgml = xmlHashCreate(10);
422 return(ret);
423}
424
431void
432xmlFreeCatalog(xmlCatalogPtr catal) {
433 if (catal == NULL)
434 return;
435 if (catal->xml != NULL)
436 xmlFreeCatalogEntryList(catal->xml);
437 if (catal->sgml != NULL)
438 xmlHashFree(catal->sgml, xmlFreeCatalogEntry);
439 xmlFree(catal);
440}
441
442/************************************************************************
443 * *
444 * Serializing Catalogs *
445 * *
446 ************************************************************************/
447
448#ifdef LIBXML_OUTPUT_ENABLED
456static void
457xmlCatalogDumpEntry(void *payload, void *data,
459 xmlCatalogEntryPtr entry = (xmlCatalogEntryPtr) payload;
460 FILE *out = (FILE *) data;
461 if ((entry == NULL) || (out == NULL))
462 return;
463 switch (entry->type) {
464 case SGML_CATA_ENTITY:
465 fprintf(out, "ENTITY "); break;
466 case SGML_CATA_PENTITY:
467 fprintf(out, "ENTITY %%"); break;
468 case SGML_CATA_DOCTYPE:
469 fprintf(out, "DOCTYPE "); break;
470 case SGML_CATA_LINKTYPE:
471 fprintf(out, "LINKTYPE "); break;
472 case SGML_CATA_NOTATION:
473 fprintf(out, "NOTATION "); break;
474 case SGML_CATA_PUBLIC:
475 fprintf(out, "PUBLIC "); break;
476 case SGML_CATA_SYSTEM:
477 fprintf(out, "SYSTEM "); break;
478 case SGML_CATA_DELEGATE:
479 fprintf(out, "DELEGATE "); break;
480 case SGML_CATA_BASE:
481 fprintf(out, "BASE "); break;
482 case SGML_CATA_CATALOG:
483 fprintf(out, "CATALOG "); break;
484 case SGML_CATA_DOCUMENT:
485 fprintf(out, "DOCUMENT "); break;
486 case SGML_CATA_SGMLDECL:
487 fprintf(out, "SGMLDECL "); break;
488 default:
489 return;
490 }
491 switch (entry->type) {
492 case SGML_CATA_ENTITY:
493 case SGML_CATA_PENTITY:
494 case SGML_CATA_DOCTYPE:
495 case SGML_CATA_LINKTYPE:
496 case SGML_CATA_NOTATION:
497 fprintf(out, "%s", (const char *) entry->name); break;
498 case SGML_CATA_PUBLIC:
499 case SGML_CATA_SYSTEM:
500 case SGML_CATA_SGMLDECL:
501 case SGML_CATA_DOCUMENT:
502 case SGML_CATA_CATALOG:
503 case SGML_CATA_BASE:
504 case SGML_CATA_DELEGATE:
505 fprintf(out, "\"%s\"", entry->name); break;
506 default:
507 break;
508 }
509 switch (entry->type) {
510 case SGML_CATA_ENTITY:
511 case SGML_CATA_PENTITY:
512 case SGML_CATA_DOCTYPE:
513 case SGML_CATA_LINKTYPE:
514 case SGML_CATA_NOTATION:
515 case SGML_CATA_PUBLIC:
516 case SGML_CATA_SYSTEM:
517 case SGML_CATA_DELEGATE:
518 fprintf(out, " \"%s\"", entry->value); break;
519 default:
520 break;
521 }
522 fprintf(out, "\n");
523}
524
536static void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog,
537 xmlDocPtr doc, xmlNsPtr ns, xmlCatalogEntryPtr cgroup) {
539 xmlCatalogEntryPtr cur;
540 /*
541 * add all the catalog entries
542 */
543 cur = catal;
544 while (cur != NULL) {
545 if (cur->group == cgroup) {
546 switch (cur->type) {
547 case XML_CATA_REMOVED:
548 break;
549 case XML_CATA_BROKEN_CATALOG:
550 case XML_CATA_CATALOG:
551 if (cur == catal) {
552 cur = cur->children;
553 continue;
554 }
555 break;
556 case XML_CATA_NEXT_CATALOG:
557 node = xmlNewDocNode(doc, ns, BAD_CAST "nextCatalog", NULL);
558 xmlSetProp(node, BAD_CAST "catalog", cur->value);
559 xmlAddChild(catalog, node);
560 break;
561 case XML_CATA_NONE:
562 break;
563 case XML_CATA_GROUP:
564 node = xmlNewDocNode(doc, ns, BAD_CAST "group", NULL);
565 xmlSetProp(node, BAD_CAST "id", cur->name);
566 if (cur->value != NULL) {
567 xmlNsPtr xns;
569 if (xns != NULL)
570 xmlSetNsProp(node, xns, BAD_CAST "base",
571 cur->value);
572 }
573 switch (cur->prefer) {
574 case XML_CATA_PREFER_NONE:
575 break;
576 case XML_CATA_PREFER_PUBLIC:
577 xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "public");
578 break;
579 case XML_CATA_PREFER_SYSTEM:
580 xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "system");
581 break;
582 }
583 xmlDumpXMLCatalogNode(cur->next, node, doc, ns, cur);
584 xmlAddChild(catalog, node);
585 break;
586 case XML_CATA_PUBLIC:
587 node = xmlNewDocNode(doc, ns, BAD_CAST "public", NULL);
588 xmlSetProp(node, BAD_CAST "publicId", cur->name);
589 xmlSetProp(node, BAD_CAST "uri", cur->value);
590 xmlAddChild(catalog, node);
591 break;
592 case XML_CATA_SYSTEM:
593 node = xmlNewDocNode(doc, ns, BAD_CAST "system", NULL);
594 xmlSetProp(node, BAD_CAST "systemId", cur->name);
595 xmlSetProp(node, BAD_CAST "uri", cur->value);
596 xmlAddChild(catalog, node);
597 break;
598 case XML_CATA_REWRITE_SYSTEM:
599 node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteSystem", NULL);
600 xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
601 xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
602 xmlAddChild(catalog, node);
603 break;
604 case XML_CATA_DELEGATE_PUBLIC:
605 node = xmlNewDocNode(doc, ns, BAD_CAST "delegatePublic", NULL);
606 xmlSetProp(node, BAD_CAST "publicIdStartString", cur->name);
607 xmlSetProp(node, BAD_CAST "catalog", cur->value);
608 xmlAddChild(catalog, node);
609 break;
610 case XML_CATA_DELEGATE_SYSTEM:
611 node = xmlNewDocNode(doc, ns, BAD_CAST "delegateSystem", NULL);
612 xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
613 xmlSetProp(node, BAD_CAST "catalog", cur->value);
614 xmlAddChild(catalog, node);
615 break;
616 case XML_CATA_URI:
617 node = xmlNewDocNode(doc, ns, BAD_CAST "uri", NULL);
618 xmlSetProp(node, BAD_CAST "name", cur->name);
619 xmlSetProp(node, BAD_CAST "uri", cur->value);
620 xmlAddChild(catalog, node);
621 break;
622 case XML_CATA_REWRITE_URI:
623 node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteURI", NULL);
624 xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
625 xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
626 xmlAddChild(catalog, node);
627 break;
628 case XML_CATA_DELEGATE_URI:
629 node = xmlNewDocNode(doc, ns, BAD_CAST "delegateURI", NULL);
630 xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
631 xmlSetProp(node, BAD_CAST "catalog", cur->value);
632 xmlAddChild(catalog, node);
633 break;
634 case SGML_CATA_SYSTEM:
635 case SGML_CATA_PUBLIC:
636 case SGML_CATA_ENTITY:
637 case SGML_CATA_PENTITY:
638 case SGML_CATA_DOCTYPE:
639 case SGML_CATA_LINKTYPE:
640 case SGML_CATA_NOTATION:
641 case SGML_CATA_DELEGATE:
642 case SGML_CATA_BASE:
643 case SGML_CATA_CATALOG:
644 case SGML_CATA_DOCUMENT:
645 case SGML_CATA_SGMLDECL:
646 break;
647 }
648 }
649 cur = cur->next;
650 }
651}
652
653static int
654xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) {
655 int ret;
656 xmlDocPtr doc;
657 xmlNsPtr ns;
658 xmlDtdPtr dtd;
659 xmlNodePtr catalog;
661
662 /*
663 * Rebuild a catalog
664 */
665 doc = xmlNewDoc(NULL);
666 if (doc == NULL)
667 return(-1);
668 dtd = xmlNewDtd(doc, BAD_CAST "catalog",
669 BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
670BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd");
671
672 xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
673
674 ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL);
675 if (ns == NULL) {
676 xmlFreeDoc(doc);
677 return(-1);
678 }
679 catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL);
680 if (catalog == NULL) {
681 xmlFreeNs(ns);
682 xmlFreeDoc(doc);
683 return(-1);
684 }
685 catalog->nsDef = ns;
686 xmlAddChild((xmlNodePtr) doc, catalog);
687
688 xmlDumpXMLCatalogNode(catal, catalog, doc, ns, NULL);
689
690 /*
691 * reserialize it
692 */
693 buf = xmlOutputBufferCreateFile(out, NULL);
694 if (buf == NULL) {
695 xmlFreeDoc(doc);
696 return(-1);
697 }
698 ret = xmlSaveFormatFileTo(buf, doc, NULL, 1);
699
700 /*
701 * Free it
702 */
703 xmlFreeDoc(doc);
704
705 return(ret);
706}
707#endif /* LIBXML_OUTPUT_ENABLED */
708
709/************************************************************************
710 * *
711 * Converting SGML Catalogs to XML *
712 * *
713 ************************************************************************/
714
722static void
723xmlCatalogConvertEntry(void *payload, void *data,
725 xmlCatalogEntryPtr entry = (xmlCatalogEntryPtr) payload;
726 xmlCatalogPtr catal = (xmlCatalogPtr) data;
727 if ((entry == NULL) || (catal == NULL) || (catal->sgml == NULL) ||
728 (catal->xml == NULL))
729 return;
730 switch (entry->type) {
731 case SGML_CATA_ENTITY:
732 entry->type = XML_CATA_PUBLIC;
733 break;
734 case SGML_CATA_PENTITY:
735 entry->type = XML_CATA_PUBLIC;
736 break;
737 case SGML_CATA_DOCTYPE:
738 entry->type = XML_CATA_PUBLIC;
739 break;
740 case SGML_CATA_LINKTYPE:
741 entry->type = XML_CATA_PUBLIC;
742 break;
743 case SGML_CATA_NOTATION:
744 entry->type = XML_CATA_PUBLIC;
745 break;
746 case SGML_CATA_PUBLIC:
747 entry->type = XML_CATA_PUBLIC;
748 break;
749 case SGML_CATA_SYSTEM:
750 entry->type = XML_CATA_SYSTEM;
751 break;
752 case SGML_CATA_DELEGATE:
753 entry->type = XML_CATA_DELEGATE_PUBLIC;
754 break;
755 case SGML_CATA_CATALOG:
756 entry->type = XML_CATA_CATALOG;
757 break;
758 default:
759 xmlHashRemoveEntry(catal->sgml, entry->name, xmlFreeCatalogEntry);
760 return;
761 }
762 /*
763 * Conversion successful, remove from the SGML catalog
764 * and add it to the default XML one
765 */
766 xmlHashRemoveEntry(catal->sgml, entry->name, NULL);
767 entry->parent = catal->xml;
768 entry->next = NULL;
769 if (catal->xml->children == NULL)
770 catal->xml->children = entry;
771 else {
772 xmlCatalogEntryPtr prev;
773
774 prev = catal->xml->children;
775 while (prev->next != NULL)
776 prev = prev->next;
777 prev->next = entry;
778 }
779}
780
789int
790xmlConvertSGMLCatalog(xmlCatalogPtr catal) {
791
792 if ((catal == NULL) || (catal->type != XML_SGML_CATALOG_TYPE))
793 return(-1);
794
795 if (xmlDebugCatalogs) {
797 "Converting SGML catalog to XML\n");
798 }
799 xmlHashScan(catal->sgml, xmlCatalogConvertEntry, &catal);
800 return(0);
801}
802
803/************************************************************************
804 * *
805 * Helper function *
806 * *
807 ************************************************************************/
808
818static xmlChar *
819xmlCatalogUnWrapURN(const xmlChar *urn) {
820 xmlChar result[2000];
821 unsigned int i = 0;
822
823 if (xmlStrncmp(urn, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1))
824 return(NULL);
825 urn += sizeof(XML_URN_PUBID) - 1;
826
827 while (*urn != 0) {
828 if (i > sizeof(result) - 4)
829 break;
830 if (*urn == '+') {
831 result[i++] = ' ';
832 urn++;
833 } else if (*urn == ':') {
834 result[i++] = '/';
835 result[i++] = '/';
836 urn++;
837 } else if (*urn == ';') {
838 result[i++] = ':';
839 result[i++] = ':';
840 urn++;
841 } else if (*urn == '%') {
842 if ((urn[1] == '2') && (urn[2] == 'B'))
843 result[i++] = '+';
844 else if ((urn[1] == '3') && (urn[2] == 'A'))
845 result[i++] = ':';
846 else if ((urn[1] == '2') && (urn[2] == 'F'))
847 result[i++] = '/';
848 else if ((urn[1] == '3') && (urn[2] == 'B'))
849 result[i++] = ';';
850 else if ((urn[1] == '2') && (urn[2] == '7'))
851 result[i++] = '\'';
852 else if ((urn[1] == '3') && (urn[2] == 'F'))
853 result[i++] = '?';
854 else if ((urn[1] == '2') && (urn[2] == '3'))
855 result[i++] = '#';
856 else if ((urn[1] == '2') && (urn[2] == '5'))
857 result[i++] = '%';
858 else {
859 result[i++] = *urn;
860 urn++;
861 continue;
862 }
863 urn += 3;
864 } else {
865 result[i++] = *urn;
866 urn++;
867 }
868 }
869 result[i] = 0;
870
871 return(xmlStrdup(result));
872}
873
885xmlParseCatalogFile(const char *filename) {
887 xmlParserCtxtPtr ctxt;
888 char *directory = NULL;
889 xmlParserInputPtr inputStream;
891
892 ctxt = xmlNewParserCtxt();
893 if (ctxt == NULL) {
894#ifdef LIBXML_SAX1_ENABLED
896 xmlDefaultSAXHandler.error(NULL, "out of memory\n");
897 }
898#endif
899 return(NULL);
900 }
901
903 if (buf == NULL) {
904 xmlFreeParserCtxt(ctxt);
905 return(NULL);
906 }
907
908 inputStream = xmlNewInputStream(ctxt);
909 if (inputStream == NULL) {
911 xmlFreeParserCtxt(ctxt);
912 return(NULL);
913 }
914
915 inputStream->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
916 inputStream->buf = buf;
917 xmlBufResetInput(buf->buffer, inputStream);
918
919 inputPush(ctxt, inputStream);
920 if (ctxt->directory == NULL)
922 if ((ctxt->directory == NULL) && (directory != NULL))
923 ctxt->directory = directory;
924 ctxt->valid = 0;
925 ctxt->validate = 0;
926 ctxt->loadsubset = 0;
927 ctxt->pedantic = 0;
928 ctxt->dictNames = 1;
929
930 xmlParseDocument(ctxt);
931
932 if (ctxt->wellFormed)
933 ret = ctxt->myDoc;
934 else {
935 ret = NULL;
936 xmlFreeDoc(ctxt->myDoc);
937 ctxt->myDoc = NULL;
938 }
939 xmlFreeParserCtxt(ctxt);
940
941 return(ret);
942}
943
952static xmlChar *
953xmlLoadFileContent(const char *filename)
954{
955#ifdef HAVE_STAT
956 int fd;
957#else
958 FILE *fd;
959#endif
960 int len;
961 long size;
962
963#ifdef HAVE_STAT
964 struct stat info;
965#endif
967
968 if (filename == NULL)
969 return (NULL);
970
971#ifdef HAVE_STAT
972 if (stat(filename, &info) < 0)
973 return (NULL);
974#endif
975
976#ifdef HAVE_STAT
977 if ((fd = open(filename, O_RDONLY)) < 0)
978#else
979 if ((fd = fopen(filename, "rb")) == NULL)
980#endif
981 {
982 return (NULL);
983 }
984#ifdef HAVE_STAT
985 size = info.st_size;
986#else
987 if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */
988 fclose(fd);
989 return (NULL);
990 }
991#endif
993 if (content == NULL) {
994 xmlCatalogErrMemory("allocating catalog data");
995#ifdef HAVE_STAT
996 close(fd);
997#else
998 fclose(fd);
999#endif
1000 return (NULL);
1001 }
1002#ifdef HAVE_STAT
1003 len = read(fd, content, size);
1004 close(fd);
1005#else
1006 len = fread(content, 1, size, fd);
1007 fclose(fd);
1008#endif
1009 if (len < 0) {
1011 return (NULL);
1012 }
1013 content[len] = 0;
1014
1015 return(content);
1016}
1017
1030static xmlChar *
1031xmlCatalogNormalizePublic(const xmlChar *pubID)
1032{
1033 int ok = 1;
1034 int white;
1035 const xmlChar *p;
1036 xmlChar *ret;
1037 xmlChar *q;
1038
1039 if (pubID == NULL)
1040 return(NULL);
1041
1042 white = 1;
1043 for (p = pubID;*p != 0 && ok;p++) {
1044 if (!xmlIsBlank_ch(*p))
1045 white = 0;
1046 else if (*p == 0x20 && !white)
1047 white = 1;
1048 else
1049 ok = 0;
1050 }
1051 if (ok && !white) /* is normalized */
1052 return(NULL);
1053
1054 ret = xmlStrdup(pubID);
1055 q = ret;
1056 white = 0;
1057 for (p = pubID;*p != 0;p++) {
1058 if (xmlIsBlank_ch(*p)) {
1059 if (q != ret)
1060 white = 1;
1061 } else {
1062 if (white) {
1063 *(q++) = 0x20;
1064 white = 0;
1065 }
1066 *(q++) = *p;
1067 }
1068 }
1069 *q = 0;
1070 return(ret);
1071}
1072
1073/************************************************************************
1074 * *
1075 * The XML Catalog parser *
1076 * *
1077 ************************************************************************/
1078
1079static xmlCatalogEntryPtr
1080xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename);
1081static void
1082xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
1083 xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup);
1084static xmlChar *
1085xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
1086 const xmlChar *sysID);
1087static xmlChar *
1088xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI);
1089
1090
1099static xmlCatalogEntryType
1100xmlGetXMLCatalogEntryType(const xmlChar *name) {
1101 xmlCatalogEntryType type = XML_CATA_NONE;
1102 if (xmlStrEqual(name, (const xmlChar *) "system"))
1103 type = XML_CATA_SYSTEM;
1104 else if (xmlStrEqual(name, (const xmlChar *) "public"))
1105 type = XML_CATA_PUBLIC;
1106 else if (xmlStrEqual(name, (const xmlChar *) "rewriteSystem"))
1107 type = XML_CATA_REWRITE_SYSTEM;
1108 else if (xmlStrEqual(name, (const xmlChar *) "delegatePublic"))
1109 type = XML_CATA_DELEGATE_PUBLIC;
1110 else if (xmlStrEqual(name, (const xmlChar *) "delegateSystem"))
1111 type = XML_CATA_DELEGATE_SYSTEM;
1112 else if (xmlStrEqual(name, (const xmlChar *) "uri"))
1113 type = XML_CATA_URI;
1114 else if (xmlStrEqual(name, (const xmlChar *) "rewriteURI"))
1115 type = XML_CATA_REWRITE_URI;
1116 else if (xmlStrEqual(name, (const xmlChar *) "delegateURI"))
1117 type = XML_CATA_DELEGATE_URI;
1118 else if (xmlStrEqual(name, (const xmlChar *) "nextCatalog"))
1119 type = XML_CATA_NEXT_CATALOG;
1120 else if (xmlStrEqual(name, (const xmlChar *) "catalog"))
1121 type = XML_CATA_CATALOG;
1122 return(type);
1123}
1124
1140static xmlCatalogEntryPtr
1141xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
1142 const xmlChar *name, const xmlChar *attrName,
1143 const xmlChar *uriAttrName, xmlCatalogPrefer prefer,
1144 xmlCatalogEntryPtr cgroup) {
1145 int ok = 1;
1146 xmlChar *uriValue;
1147 xmlChar *nameValue = NULL;
1148 xmlChar *base = NULL;
1149 xmlChar *URL = NULL;
1150 xmlCatalogEntryPtr ret = NULL;
1151
1152 if (attrName != NULL) {
1153 nameValue = xmlGetProp(cur, attrName);
1154 if (nameValue == NULL) {
1155 xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
1156 "%s entry lacks '%s'\n", name, attrName, NULL);
1157 ok = 0;
1158 }
1159 }
1160 uriValue = xmlGetProp(cur, uriAttrName);
1161 if (uriValue == NULL) {
1162 xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
1163 "%s entry lacks '%s'\n", name, uriAttrName, NULL);
1164 ok = 0;
1165 }
1166 if (!ok) {
1167 if (nameValue != NULL)
1168 xmlFree(nameValue);
1169 if (uriValue != NULL)
1170 xmlFree(uriValue);
1171 return(NULL);
1172 }
1173
1174 base = xmlNodeGetBase(cur->doc, cur);
1175 URL = xmlBuildURI(uriValue, base);
1176 if (URL != NULL) {
1177 if (xmlDebugCatalogs > 1) {
1178 if (nameValue != NULL)
1180 "Found %s: '%s' '%s'\n", name, nameValue, URL);
1181 else
1183 "Found %s: '%s'\n", name, URL);
1184 }
1185 ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer, cgroup);
1186 } else {
1187 xmlCatalogErr(ret, cur, XML_CATALOG_ENTRY_BROKEN,
1188 "%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);
1189 }
1190 if (nameValue != NULL)
1191 xmlFree(nameValue);
1192 if (uriValue != NULL)
1193 xmlFree(uriValue);
1194 if (base != NULL)
1195 xmlFree(base);
1196 if (URL != NULL)
1197 xmlFree(URL);
1198 return(ret);
1199}
1200
1212static void
1213xmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer,
1214 xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup)
1215{
1216 xmlChar *base = NULL;
1217 xmlCatalogEntryPtr entry = NULL;
1218
1219 if (cur == NULL)
1220 return;
1221 if (xmlStrEqual(cur->name, BAD_CAST "group")) {
1222 xmlChar *prop;
1223 xmlCatalogPrefer pref = XML_CATA_PREFER_NONE;
1224
1225 prop = xmlGetProp(cur, BAD_CAST "prefer");
1226 if (prop != NULL) {
1227 if (xmlStrEqual(prop, BAD_CAST "system")) {
1228 prefer = XML_CATA_PREFER_SYSTEM;
1229 } else if (xmlStrEqual(prop, BAD_CAST "public")) {
1230 prefer = XML_CATA_PREFER_PUBLIC;
1231 } else {
1232 xmlCatalogErr(parent, cur, XML_CATALOG_PREFER_VALUE,
1233 "Invalid value for prefer: '%s'\n",
1234 prop, NULL, NULL);
1235 }
1236 xmlFree(prop);
1237 pref = prefer;
1238 }
1239 prop = xmlGetProp(cur, BAD_CAST "id");
1241 entry = xmlNewCatalogEntry(XML_CATA_GROUP, prop, base, NULL, pref, cgroup);
1242 xmlFree(prop);
1243 } else if (xmlStrEqual(cur->name, BAD_CAST "public")) {
1244 entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,
1245 BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer, cgroup);
1246 } else if (xmlStrEqual(cur->name, BAD_CAST "system")) {
1247 entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,
1248 BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer, cgroup);
1249 } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {
1250 entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,
1251 BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",
1252 BAD_CAST "rewritePrefix", prefer, cgroup);
1253 } else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {
1254 entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,
1255 BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",
1256 BAD_CAST "catalog", prefer, cgroup);
1257 } else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {
1258 entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,
1259 BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",
1260 BAD_CAST "catalog", prefer, cgroup);
1261 } else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {
1262 entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,
1263 BAD_CAST "uri", BAD_CAST "name",
1264 BAD_CAST "uri", prefer, cgroup);
1265 } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {
1266 entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,
1267 BAD_CAST "rewriteURI", BAD_CAST "uriStartString",
1268 BAD_CAST "rewritePrefix", prefer, cgroup);
1269 } else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {
1270 entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,
1271 BAD_CAST "delegateURI", BAD_CAST "uriStartString",
1272 BAD_CAST "catalog", prefer, cgroup);
1273 } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {
1274 entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,
1275 BAD_CAST "nextCatalog", NULL,
1276 BAD_CAST "catalog", prefer, cgroup);
1277 }
1278 if (entry != NULL) {
1279 if (parent != NULL) {
1280 entry->parent = parent;
1281 if (parent->children == NULL)
1282 parent->children = entry;
1283 else {
1284 xmlCatalogEntryPtr prev;
1285
1286 prev = parent->children;
1287 while (prev->next != NULL)
1288 prev = prev->next;
1289 prev->next = entry;
1290 }
1291 }
1292 if (entry->type == XML_CATA_GROUP) {
1293 /*
1294 * Recurse to propagate prefer to the subtree
1295 * (xml:base handling is automated)
1296 */
1297 xmlParseXMLCatalogNodeList(cur->children, prefer, parent, entry);
1298 }
1299 }
1300 if (base != NULL)
1301 xmlFree(base);
1302}
1303
1315static void
1316xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
1317 xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup) {
1318 while (cur != NULL) {
1319 if ((cur->ns != NULL) && (cur->ns->href != NULL) &&
1320 (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
1321 xmlParseXMLCatalogNode(cur, prefer, parent, cgroup);
1322 }
1323 cur = cur->next;
1324 }
1325 /* TODO: sort the list according to REWRITE lengths and prefer value */
1326}
1327
1338static xmlCatalogEntryPtr
1339xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {
1340 xmlDocPtr doc;
1342 xmlChar *prop;
1343 xmlCatalogEntryPtr parent = NULL;
1344
1345 if (filename == NULL)
1346 return(NULL);
1347
1348 doc = xmlParseCatalogFile((const char *) filename);
1349 if (doc == NULL) {
1350 if (xmlDebugCatalogs)
1352 "Failed to parse catalog %s\n", filename);
1353 return(NULL);
1354 }
1355
1356 if (xmlDebugCatalogs)
1358 "%d Parsing catalog %s\n", xmlGetThreadId(), filename);
1359
1361 if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&
1362 (cur->ns != NULL) && (cur->ns->href != NULL) &&
1363 (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
1364
1365 parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
1366 (const xmlChar *)filename, NULL, prefer, NULL);
1367 if (parent == NULL) {
1368 xmlFreeDoc(doc);
1369 return(NULL);
1370 }
1371
1372 prop = xmlGetProp(cur, BAD_CAST "prefer");
1373 if (prop != NULL) {
1374 if (xmlStrEqual(prop, BAD_CAST "system")) {
1375 prefer = XML_CATA_PREFER_SYSTEM;
1376 } else if (xmlStrEqual(prop, BAD_CAST "public")) {
1377 prefer = XML_CATA_PREFER_PUBLIC;
1378 } else {
1379 xmlCatalogErr(NULL, cur, XML_CATALOG_PREFER_VALUE,
1380 "Invalid value for prefer: '%s'\n",
1381 prop, NULL, NULL);
1382 }
1383 xmlFree(prop);
1384 }
1385 cur = cur->children;
1386 xmlParseXMLCatalogNodeList(cur, prefer, parent, NULL);
1387 } else {
1388 xmlCatalogErr(NULL, (xmlNodePtr) doc, XML_CATALOG_NOT_CATALOG,
1389 "File %s is not an XML Catalog\n",
1390 filename, NULL, NULL);
1391 xmlFreeDoc(doc);
1392 return(NULL);
1393 }
1394 xmlFreeDoc(doc);
1395 return(parent);
1396}
1397
1406static int
1407xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
1408 xmlCatalogEntryPtr doc;
1409
1410 if (catal == NULL)
1411 return(-1);
1412 if (catal->URL == NULL)
1413 return(-1);
1414
1415 /*
1416 * lock the whole catalog for modification
1417 */
1418 xmlRMutexLock(xmlCatalogMutex);
1419 if (catal->children != NULL) {
1420 /* Okay someone else did it in the meantime */
1421 xmlRMutexUnlock(xmlCatalogMutex);
1422 return(0);
1423 }
1424
1425 if (xmlCatalogXMLFiles != NULL) {
1426 doc = (xmlCatalogEntryPtr)
1427 xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
1428 if (doc != NULL) {
1429 if (xmlDebugCatalogs)
1431 "Found %s in file hash\n", catal->URL);
1432
1433 if (catal->type == XML_CATA_CATALOG)
1434 catal->children = doc->children;
1435 else
1436 catal->children = doc;
1437 catal->dealloc = 0;
1438 xmlRMutexUnlock(xmlCatalogMutex);
1439 return(0);
1440 }
1441 if (xmlDebugCatalogs)
1443 "%s not found in file hash\n", catal->URL);
1444 }
1445
1446 /*
1447 * Fetch and parse. Note that xmlParseXMLCatalogFile does not
1448 * use the existing catalog, there is no recursion allowed at
1449 * that level.
1450 */
1451 doc = xmlParseXMLCatalogFile(catal->prefer, catal->URL);
1452 if (doc == NULL) {
1453 catal->type = XML_CATA_BROKEN_CATALOG;
1454 xmlRMutexUnlock(xmlCatalogMutex);
1455 return(-1);
1456 }
1457
1458 if (catal->type == XML_CATA_CATALOG)
1459 catal->children = doc->children;
1460 else
1461 catal->children = doc;
1462
1463 doc->dealloc = 1;
1464
1465 if (xmlCatalogXMLFiles == NULL)
1466 xmlCatalogXMLFiles = xmlHashCreate(10);
1467 if (xmlCatalogXMLFiles != NULL) {
1468 if (xmlDebugCatalogs)
1470 "%s added to file hash\n", catal->URL);
1471 xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc);
1472 }
1473 xmlRMutexUnlock(xmlCatalogMutex);
1474 return(0);
1475}
1476
1477/************************************************************************
1478 * *
1479 * XML Catalog handling *
1480 * *
1481 ************************************************************************/
1482
1495static int
1496xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
1497 const xmlChar *orig, const xmlChar *replace) {
1498 xmlCatalogEntryPtr cur;
1499 xmlCatalogEntryType typ;
1500 int doregister = 0;
1501
1502 if ((catal == NULL) ||
1503 ((catal->type != XML_CATA_CATALOG) &&
1504 (catal->type != XML_CATA_BROKEN_CATALOG)))
1505 return(-1);
1506 if (catal->children == NULL) {
1507 xmlFetchXMLCatalogFile(catal);
1508 }
1509 if (catal->children == NULL)
1510 doregister = 1;
1511
1512 typ = xmlGetXMLCatalogEntryType(type);
1513 if (typ == XML_CATA_NONE) {
1514 if (xmlDebugCatalogs)
1516 "Failed to add unknown element %s to catalog\n", type);
1517 return(-1);
1518 }
1519
1520 cur = catal->children;
1521 /*
1522 * Might be a simple "update in place"
1523 */
1524 if (cur != NULL) {
1525 while (cur != NULL) {
1526 if ((orig != NULL) && (cur->type == typ) &&
1527 (xmlStrEqual(orig, cur->name))) {
1528 if (xmlDebugCatalogs)
1530 "Updating element %s to catalog\n", type);
1531 if (cur->value != NULL)
1532 xmlFree(cur->value);
1533 if (cur->URL != NULL)
1534 xmlFree(cur->URL);
1535 cur->value = xmlStrdup(replace);
1536 cur->URL = xmlStrdup(replace);
1537 return(0);
1538 }
1539 if (cur->next == NULL)
1540 break;
1541 cur = cur->next;
1542 }
1543 }
1544 if (xmlDebugCatalogs)
1546 "Adding element %s to catalog\n", type);
1547 if (cur == NULL)
1548 catal->children = xmlNewCatalogEntry(typ, orig, replace,
1549 NULL, catal->prefer, NULL);
1550 else
1551 cur->next = xmlNewCatalogEntry(typ, orig, replace,
1552 NULL, catal->prefer, NULL);
1553 if (doregister) {
1554 catal->type = XML_CATA_CATALOG;
1555 cur = (xmlCatalogEntryPtr)xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
1556 if (cur != NULL)
1557 cur->children = catal->children;
1558 }
1559
1560 return(0);
1561}
1562
1573static int
1574xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
1575 xmlCatalogEntryPtr cur;
1576 int ret = 0;
1577
1578 if ((catal == NULL) ||
1579 ((catal->type != XML_CATA_CATALOG) &&
1580 (catal->type != XML_CATA_BROKEN_CATALOG)))
1581 return(-1);
1582 if (value == NULL)
1583 return(-1);
1584 if (catal->children == NULL) {
1585 xmlFetchXMLCatalogFile(catal);
1586 }
1587
1588 /*
1589 * Scan the children
1590 */
1591 cur = catal->children;
1592 while (cur != NULL) {
1593 if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) ||
1594 (xmlStrEqual(value, cur->value))) {
1595 if (xmlDebugCatalogs) {
1596 if (cur->name != NULL)
1598 "Removing element %s from catalog\n", cur->name);
1599 else
1601 "Removing element %s from catalog\n", cur->value);
1602 }
1603 cur->type = XML_CATA_REMOVED;
1604 }
1605 cur = cur->next;
1606 }
1607 return(ret);
1608}
1609
1624static xmlChar *
1625xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
1626 const xmlChar *sysID) {
1627 xmlChar *ret = NULL;
1628 xmlCatalogEntryPtr cur;
1629 int haveDelegate = 0;
1630 int haveNext = 0;
1631
1632 /*
1633 * protection against loops
1634 */
1635 if (catal->depth > MAX_CATAL_DEPTH) {
1636 xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
1637 "Detected recursion in catalog %s\n",
1638 catal->name, NULL, NULL);
1639 return(NULL);
1640 }
1641 catal->depth++;
1642
1643 /*
1644 * First tries steps 2/ 3/ 4/ if a system ID is provided.
1645 */
1646 if (sysID != NULL) {
1647 xmlCatalogEntryPtr rewrite = NULL;
1648 int lenrewrite = 0, len;
1649 cur = catal;
1650 haveDelegate = 0;
1651 while (cur != NULL) {
1652 switch (cur->type) {
1653 case XML_CATA_SYSTEM:
1654 if (xmlStrEqual(sysID, cur->name)) {
1655 if (xmlDebugCatalogs)
1657 "Found system match %s, using %s\n",
1658 cur->name, cur->URL);
1659 catal->depth--;
1660 return(xmlStrdup(cur->URL));
1661 }
1662 break;
1663 case XML_CATA_REWRITE_SYSTEM:
1664 len = xmlStrlen(cur->name);
1665 if ((len > lenrewrite) &&
1666 (!xmlStrncmp(sysID, cur->name, len))) {
1667 lenrewrite = len;
1668 rewrite = cur;
1669 }
1670 break;
1671 case XML_CATA_DELEGATE_SYSTEM:
1672 if (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))
1673 haveDelegate++;
1674 break;
1675 case XML_CATA_NEXT_CATALOG:
1676 haveNext++;
1677 break;
1678 default:
1679 break;
1680 }
1681 cur = cur->next;
1682 }
1683 if (rewrite != NULL) {
1684 if (xmlDebugCatalogs)
1686 "Using rewriting rule %s\n", rewrite->name);
1687 ret = xmlStrdup(rewrite->URL);
1688 if (ret != NULL)
1689 ret = xmlStrcat(ret, &sysID[lenrewrite]);
1690 catal->depth--;
1691 return(ret);
1692 }
1693 if (haveDelegate) {
1694 const xmlChar *delegates[MAX_DELEGATE];
1695 int nbList = 0, i;
1696
1697 /*
1698 * Assume the entries have been sorted by decreasing substring
1699 * matches when the list was produced.
1700 */
1701 cur = catal;
1702 while (cur != NULL) {
1703 if ((cur->type == XML_CATA_DELEGATE_SYSTEM) &&
1704 (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))) {
1705 for (i = 0;i < nbList;i++)
1706 if (xmlStrEqual(cur->URL, delegates[i]))
1707 break;
1708 if (i < nbList) {
1709 cur = cur->next;
1710 continue;
1711 }
1712 if (nbList < MAX_DELEGATE)
1713 delegates[nbList++] = cur->URL;
1714
1715 if (cur->children == NULL) {
1716 xmlFetchXMLCatalogFile(cur);
1717 }
1718 if (cur->children != NULL) {
1719 if (xmlDebugCatalogs)
1721 "Trying system delegate %s\n", cur->URL);
1722 ret = xmlCatalogListXMLResolve(
1723 cur->children, NULL, sysID);
1724 if (ret != NULL) {
1725 catal->depth--;
1726 return(ret);
1727 }
1728 }
1729 }
1730 cur = cur->next;
1731 }
1732 /*
1733 * Apply the cut algorithm explained in 4/
1734 */
1735 catal->depth--;
1736 return(XML_CATAL_BREAK);
1737 }
1738 }
1739 /*
1740 * Then tries 5/ 6/ if a public ID is provided
1741 */
1742 if (pubID != NULL) {
1743 cur = catal;
1744 haveDelegate = 0;
1745 while (cur != NULL) {
1746 switch (cur->type) {
1747 case XML_CATA_PUBLIC:
1748 if (xmlStrEqual(pubID, cur->name)) {
1749 if (xmlDebugCatalogs)
1751 "Found public match %s\n", cur->name);
1752 catal->depth--;
1753 return(xmlStrdup(cur->URL));
1754 }
1755 break;
1756 case XML_CATA_DELEGATE_PUBLIC:
1757 if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) &&
1758 (cur->prefer == XML_CATA_PREFER_PUBLIC))
1759 haveDelegate++;
1760 break;
1761 case XML_CATA_NEXT_CATALOG:
1762 if (sysID == NULL)
1763 haveNext++;
1764 break;
1765 default:
1766 break;
1767 }
1768 cur = cur->next;
1769 }
1770 if (haveDelegate) {
1771 const xmlChar *delegates[MAX_DELEGATE];
1772 int nbList = 0, i;
1773
1774 /*
1775 * Assume the entries have been sorted by decreasing substring
1776 * matches when the list was produced.
1777 */
1778 cur = catal;
1779 while (cur != NULL) {
1780 if ((cur->type == XML_CATA_DELEGATE_PUBLIC) &&
1781 (cur->prefer == XML_CATA_PREFER_PUBLIC) &&
1782 (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))) {
1783
1784 for (i = 0;i < nbList;i++)
1785 if (xmlStrEqual(cur->URL, delegates[i]))
1786 break;
1787 if (i < nbList) {
1788 cur = cur->next;
1789 continue;
1790 }
1791 if (nbList < MAX_DELEGATE)
1792 delegates[nbList++] = cur->URL;
1793
1794 if (cur->children == NULL) {
1795 xmlFetchXMLCatalogFile(cur);
1796 }
1797 if (cur->children != NULL) {
1798 if (xmlDebugCatalogs)
1800 "Trying public delegate %s\n", cur->URL);
1801 ret = xmlCatalogListXMLResolve(
1802 cur->children, pubID, NULL);
1803 if (ret != NULL) {
1804 catal->depth--;
1805 return(ret);
1806 }
1807 }
1808 }
1809 cur = cur->next;
1810 }
1811 /*
1812 * Apply the cut algorithm explained in 4/
1813 */
1814 catal->depth--;
1815 return(XML_CATAL_BREAK);
1816 }
1817 }
1818 if (haveNext) {
1819 cur = catal;
1820 while (cur != NULL) {
1821 if (cur->type == XML_CATA_NEXT_CATALOG) {
1822 if (cur->children == NULL) {
1823 xmlFetchXMLCatalogFile(cur);
1824 }
1825 if (cur->children != NULL) {
1826 ret = xmlCatalogListXMLResolve(cur->children, pubID, sysID);
1827 if (ret != NULL) {
1828 catal->depth--;
1829 return(ret);
1830 } else if (catal->depth > MAX_CATAL_DEPTH) {
1831 return(NULL);
1832 }
1833 }
1834 }
1835 cur = cur->next;
1836 }
1837 }
1838
1839 catal->depth--;
1840 return(NULL);
1841}
1842
1857static xmlChar *
1858xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
1859 xmlChar *ret = NULL;
1860 xmlCatalogEntryPtr cur;
1861 int haveDelegate = 0;
1862 int haveNext = 0;
1863 xmlCatalogEntryPtr rewrite = NULL;
1864 int lenrewrite = 0, len;
1865
1866 if (catal == NULL)
1867 return(NULL);
1868
1869 if (URI == NULL)
1870 return(NULL);
1871
1872 if (catal->depth > MAX_CATAL_DEPTH) {
1873 xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
1874 "Detected recursion in catalog %s\n",
1875 catal->name, NULL, NULL);
1876 return(NULL);
1877 }
1878
1879 /*
1880 * First tries steps 2/ 3/ 4/ if a system ID is provided.
1881 */
1882 cur = catal;
1883 haveDelegate = 0;
1884 while (cur != NULL) {
1885 switch (cur->type) {
1886 case XML_CATA_URI:
1887 if (xmlStrEqual(URI, cur->name)) {
1888 if (xmlDebugCatalogs)
1890 "Found URI match %s\n", cur->name);
1891 return(xmlStrdup(cur->URL));
1892 }
1893 break;
1894 case XML_CATA_REWRITE_URI:
1895 len = xmlStrlen(cur->name);
1896 if ((len > lenrewrite) &&
1897 (!xmlStrncmp(URI, cur->name, len))) {
1898 lenrewrite = len;
1899 rewrite = cur;
1900 }
1901 break;
1902 case XML_CATA_DELEGATE_URI:
1903 if (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))
1904 haveDelegate++;
1905 break;
1906 case XML_CATA_NEXT_CATALOG:
1907 haveNext++;
1908 break;
1909 default:
1910 break;
1911 }
1912 cur = cur->next;
1913 }
1914 if (rewrite != NULL) {
1915 if (xmlDebugCatalogs)
1917 "Using rewriting rule %s\n", rewrite->name);
1918 ret = xmlStrdup(rewrite->URL);
1919 if (ret != NULL)
1920 ret = xmlStrcat(ret, &URI[lenrewrite]);
1921 return(ret);
1922 }
1923 if (haveDelegate) {
1924 const xmlChar *delegates[MAX_DELEGATE];
1925 int nbList = 0, i;
1926
1927 /*
1928 * Assume the entries have been sorted by decreasing substring
1929 * matches when the list was produced.
1930 */
1931 cur = catal;
1932 while (cur != NULL) {
1933 if (((cur->type == XML_CATA_DELEGATE_SYSTEM) ||
1934 (cur->type == XML_CATA_DELEGATE_URI)) &&
1935 (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))) {
1936 for (i = 0;i < nbList;i++)
1937 if (xmlStrEqual(cur->URL, delegates[i]))
1938 break;
1939 if (i < nbList) {
1940 cur = cur->next;
1941 continue;
1942 }
1943 if (nbList < MAX_DELEGATE)
1944 delegates[nbList++] = cur->URL;
1945
1946 if (cur->children == NULL) {
1947 xmlFetchXMLCatalogFile(cur);
1948 }
1949 if (cur->children != NULL) {
1950 if (xmlDebugCatalogs)
1952 "Trying URI delegate %s\n", cur->URL);
1953 ret = xmlCatalogListXMLResolveURI(
1954 cur->children, URI);
1955 if (ret != NULL)
1956 return(ret);
1957 }
1958 }
1959 cur = cur->next;
1960 }
1961 /*
1962 * Apply the cut algorithm explained in 4/
1963 */
1964 return(XML_CATAL_BREAK);
1965 }
1966 if (haveNext) {
1967 cur = catal;
1968 while (cur != NULL) {
1969 if (cur->type == XML_CATA_NEXT_CATALOG) {
1970 if (cur->children == NULL) {
1971 xmlFetchXMLCatalogFile(cur);
1972 }
1973 if (cur->children != NULL) {
1974 ret = xmlCatalogListXMLResolveURI(cur->children, URI);
1975 if (ret != NULL)
1976 return(ret);
1977 }
1978 }
1979 cur = cur->next;
1980 }
1981 }
1982
1983 return(NULL);
1984}
1985
2000static xmlChar *
2001xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
2002 const xmlChar *sysID) {
2003 xmlChar *ret = NULL;
2004 xmlChar *urnID = NULL;
2005 xmlChar *normid;
2006
2007 if (catal == NULL)
2008 return(NULL);
2009 if ((pubID == NULL) && (sysID == NULL))
2010 return(NULL);
2011
2012 normid = xmlCatalogNormalizePublic(pubID);
2013 if (normid != NULL)
2014 pubID = (*normid != 0 ? normid : NULL);
2015
2016 if (!xmlStrncmp(pubID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
2017 urnID = xmlCatalogUnWrapURN(pubID);
2018 if (xmlDebugCatalogs) {
2019 if (urnID == NULL)
2021 "Public URN ID %s expanded to NULL\n", pubID);
2022 else
2024 "Public URN ID expanded to %s\n", urnID);
2025 }
2026 ret = xmlCatalogListXMLResolve(catal, urnID, sysID);
2027 if (urnID != NULL)
2028 xmlFree(urnID);
2029 if (normid != NULL)
2030 xmlFree(normid);
2031 return(ret);
2032 }
2033 if (!xmlStrncmp(sysID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
2034 urnID = xmlCatalogUnWrapURN(sysID);
2035 if (xmlDebugCatalogs) {
2036 if (urnID == NULL)
2038 "System URN ID %s expanded to NULL\n", sysID);
2039 else
2041 "System URN ID expanded to %s\n", urnID);
2042 }
2043 if (pubID == NULL)
2044 ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
2045 else if (xmlStrEqual(pubID, urnID))
2046 ret = xmlCatalogListXMLResolve(catal, pubID, NULL);
2047 else {
2048 ret = xmlCatalogListXMLResolve(catal, pubID, urnID);
2049 }
2050 if (urnID != NULL)
2051 xmlFree(urnID);
2052 if (normid != NULL)
2053 xmlFree(normid);
2054 return(ret);
2055 }
2056 while (catal != NULL) {
2057 if (catal->type == XML_CATA_CATALOG) {
2058 if (catal->children == NULL) {
2059 xmlFetchXMLCatalogFile(catal);
2060 }
2061 if (catal->children != NULL) {
2062 ret = xmlCatalogXMLResolve(catal->children, pubID, sysID);
2063 if (ret != NULL) {
2064 break;
2065 } else if (catal->children->depth > MAX_CATAL_DEPTH) {
2066 ret = NULL;
2067 break;
2068 }
2069 }
2070 }
2071 catal = catal->next;
2072 }
2073 if (normid != NULL)
2074 xmlFree(normid);
2075 return(ret);
2076}
2077
2090static xmlChar *
2091xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
2092 xmlChar *ret = NULL;
2093 xmlChar *urnID = NULL;
2094
2095 if (catal == NULL)
2096 return(NULL);
2097 if (URI == NULL)
2098 return(NULL);
2099
2100 if (!xmlStrncmp(URI, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
2101 urnID = xmlCatalogUnWrapURN(URI);
2102 if (xmlDebugCatalogs) {
2103 if (urnID == NULL)
2105 "URN ID %s expanded to NULL\n", URI);
2106 else
2108 "URN ID expanded to %s\n", urnID);
2109 }
2110 ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
2111 if (urnID != NULL)
2112 xmlFree(urnID);
2113 return(ret);
2114 }
2115 while (catal != NULL) {
2116 if (catal->type == XML_CATA_CATALOG) {
2117 if (catal->children == NULL) {
2118 xmlFetchXMLCatalogFile(catal);
2119 }
2120 if (catal->children != NULL) {
2121 ret = xmlCatalogXMLResolveURI(catal->children, URI);
2122 if (ret != NULL)
2123 return(ret);
2124 }
2125 }
2126 catal = catal->next;
2127 }
2128 return(ret);
2129}
2130
2131/************************************************************************
2132 * *
2133 * The SGML Catalog parser *
2134 * *
2135 ************************************************************************/
2136
2137
2138#define RAW *cur
2139#define NEXT cur++;
2140#define SKIP(x) cur += x;
2141
2142#define SKIP_BLANKS while (IS_BLANK_CH(*cur)) NEXT;
2143
2152static const xmlChar *
2153xmlParseSGMLCatalogComment(const xmlChar *cur) {
2154 if ((cur[0] != '-') || (cur[1] != '-'))
2155 return(cur);
2156 SKIP(2);
2157 while ((cur[0] != 0) && ((cur[0] != '-') || ((cur[1] != '-'))))
2158 NEXT;
2159 if (cur[0] == 0) {
2160 return(NULL);
2161 }
2162 return(cur + 2);
2163}
2164
2174static const xmlChar *
2175xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) {
2176 xmlChar *buf = NULL, *tmp;
2177 int len = 0;
2178 int size = 50;
2179 xmlChar stop;
2180 int count = 0;
2181
2182 *id = NULL;
2183
2184 if (RAW == '"') {
2185 NEXT;
2186 stop = '"';
2187 } else if (RAW == '\'') {
2188 NEXT;
2189 stop = '\'';
2190 } else {
2191 stop = ' ';
2192 }
2193 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
2194 if (buf == NULL) {
2195 xmlCatalogErrMemory("allocating public ID");
2196 return(NULL);
2197 }
2198 while (IS_PUBIDCHAR_CH(*cur) || (*cur == '?')) {
2199 if ((*cur == stop) && (stop != ' '))
2200 break;
2201 if ((stop == ' ') && (IS_BLANK_CH(*cur)))
2202 break;
2203 if (len + 1 >= size) {
2204 size *= 2;
2205 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
2206 if (tmp == NULL) {
2207 xmlCatalogErrMemory("allocating public ID");
2208 xmlFree(buf);
2209 return(NULL);
2210 }
2211 buf = tmp;
2212 }
2213 buf[len++] = *cur;
2214 count++;
2215 NEXT;
2216 }
2217 buf[len] = 0;
2218 if (stop == ' ') {
2219 if (!IS_BLANK_CH(*cur)) {
2220 xmlFree(buf);
2221 return(NULL);
2222 }
2223 } else {
2224 if (*cur != stop) {
2225 xmlFree(buf);
2226 return(NULL);
2227 }
2228 NEXT;
2229 }
2230 *id = buf;
2231 return(cur);
2232}
2233
2243static const xmlChar *
2244xmlParseSGMLCatalogName(const xmlChar *cur, xmlChar **name) {
2246 int len = 0;
2247 int c;
2248
2249 *name = NULL;
2250
2251 /*
2252 * Handler for more complex cases
2253 */
2254 c = *cur;
2255 if ((!IS_LETTER(c) && (c != '_') && (c != ':'))) {
2256 return(NULL);
2257 }
2258
2259 while (((IS_LETTER(c)) || (IS_DIGIT(c)) ||
2260 (c == '.') || (c == '-') ||
2261 (c == '_') || (c == ':'))) {
2262 buf[len++] = c;
2263 cur++;
2264 c = *cur;
2265 if (len >= XML_MAX_NAMELEN)
2266 return(NULL);
2267 }
2268 *name = xmlStrndup(buf, len);
2269 return(cur);
2270}
2271
2280static xmlCatalogEntryType
2281xmlGetSGMLCatalogEntryType(const xmlChar *name) {
2282 xmlCatalogEntryType type = XML_CATA_NONE;
2283 if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
2284 type = SGML_CATA_SYSTEM;
2285 else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
2286 type = SGML_CATA_PUBLIC;
2287 else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
2288 type = SGML_CATA_DELEGATE;
2289 else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
2290 type = SGML_CATA_ENTITY;
2291 else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
2292 type = SGML_CATA_DOCTYPE;
2293 else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
2294 type = SGML_CATA_LINKTYPE;
2295 else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
2296 type = SGML_CATA_NOTATION;
2297 else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
2298 type = SGML_CATA_SGMLDECL;
2299 else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
2300 type = SGML_CATA_DOCUMENT;
2301 else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
2302 type = SGML_CATA_CATALOG;
2303 else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
2304 type = SGML_CATA_BASE;
2305 return(type);
2306}
2307
2321static int
2322xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value,
2323 const char *file, int super) {
2324 const xmlChar *cur = value;
2325 xmlChar *base = NULL;
2326 int res;
2327
2328 if ((cur == NULL) || (file == NULL))
2329 return(-1);
2330 base = xmlStrdup((const xmlChar *) file);
2331
2332 while ((cur != NULL) && (cur[0] != 0)) {
2334 if (cur[0] == 0)
2335 break;
2336 if ((cur[0] == '-') && (cur[1] == '-')) {
2337 cur = xmlParseSGMLCatalogComment(cur);
2338 if (cur == NULL) {
2339 /* error */
2340 break;
2341 }
2342 } else {
2343 xmlChar *sysid = NULL;
2344 xmlChar *name = NULL;
2345 xmlCatalogEntryType type = XML_CATA_NONE;
2346
2347 cur = xmlParseSGMLCatalogName(cur, &name);
2348 if (cur == NULL || name == NULL) {
2349 /* error */
2350 break;
2351 }
2352 if (!IS_BLANK_CH(*cur)) {
2353 /* error */
2354 xmlFree(name);
2355 break;
2356 }
2358 if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
2359 type = SGML_CATA_SYSTEM;
2360 else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
2361 type = SGML_CATA_PUBLIC;
2362 else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
2363 type = SGML_CATA_DELEGATE;
2364 else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
2365 type = SGML_CATA_ENTITY;
2366 else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
2367 type = SGML_CATA_DOCTYPE;
2368 else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
2369 type = SGML_CATA_LINKTYPE;
2370 else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
2371 type = SGML_CATA_NOTATION;
2372 else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
2373 type = SGML_CATA_SGMLDECL;
2374 else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
2375 type = SGML_CATA_DOCUMENT;
2376 else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
2377 type = SGML_CATA_CATALOG;
2378 else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
2379 type = SGML_CATA_BASE;
2380 else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) {
2381 xmlFree(name);
2382 cur = xmlParseSGMLCatalogName(cur, &name);
2383 if (name == NULL) {
2384 /* error */
2385 break;
2386 }
2387 xmlFree(name);
2388 continue;
2389 }
2390 xmlFree(name);
2391 name = NULL;
2392
2393 switch(type) {
2394 case SGML_CATA_ENTITY:
2395 if (*cur == '%')
2396 type = SGML_CATA_PENTITY;
2397 /* Falls through. */
2398 case SGML_CATA_PENTITY:
2399 case SGML_CATA_DOCTYPE:
2400 case SGML_CATA_LINKTYPE:
2401 case SGML_CATA_NOTATION:
2402 cur = xmlParseSGMLCatalogName(cur, &name);
2403 if (cur == NULL) {
2404 /* error */
2405 break;
2406 }
2407 if (!IS_BLANK_CH(*cur)) {
2408 /* error */
2409 break;
2410 }
2412 cur = xmlParseSGMLCatalogPubid(cur, &sysid);
2413 if (cur == NULL) {
2414 /* error */
2415 break;
2416 }
2417 break;
2418 case SGML_CATA_PUBLIC:
2419 case SGML_CATA_SYSTEM:
2420 case SGML_CATA_DELEGATE:
2421 cur = xmlParseSGMLCatalogPubid(cur, &name);
2422 if (cur == NULL) {
2423 /* error */
2424 break;
2425 }
2426 if (type != SGML_CATA_SYSTEM) {
2427 xmlChar *normid;
2428
2429 normid = xmlCatalogNormalizePublic(name);
2430 if (normid != NULL) {
2431 if (name != NULL)
2432 xmlFree(name);
2433 if (*normid != 0)
2434 name = normid;
2435 else {
2436 xmlFree(normid);
2437 name = NULL;
2438 }
2439 }
2440 }
2441 if (!IS_BLANK_CH(*cur)) {
2442 /* error */
2443 break;
2444 }
2446 cur = xmlParseSGMLCatalogPubid(cur, &sysid);
2447 if (cur == NULL) {
2448 /* error */
2449 break;
2450 }
2451 break;
2452 case SGML_CATA_BASE:
2453 case SGML_CATA_CATALOG:
2454 case SGML_CATA_DOCUMENT:
2455 case SGML_CATA_SGMLDECL:
2456 cur = xmlParseSGMLCatalogPubid(cur, &sysid);
2457 if (cur == NULL) {
2458 /* error */
2459 break;
2460 }
2461 break;
2462 default:
2463 break;
2464 }
2465 if (cur == NULL) {
2466 if (name != NULL)
2467 xmlFree(name);
2468 if (sysid != NULL)
2469 xmlFree(sysid);
2470 break;
2471 } else if (type == SGML_CATA_BASE) {
2472 if (base != NULL)
2473 xmlFree(base);
2474 base = xmlStrdup(sysid);
2475 } else if ((type == SGML_CATA_PUBLIC) ||
2476 (type == SGML_CATA_SYSTEM)) {
2478
2479 filename = xmlBuildURI(sysid, base);
2480 if (filename != NULL) {
2481 xmlCatalogEntryPtr entry;
2482
2483 entry = xmlNewCatalogEntry(type, name, filename,
2484 NULL, XML_CATA_PREFER_NONE, NULL);
2485 res = xmlHashAddEntry(catal->sgml, name, entry);
2486 if (res < 0) {
2487 xmlFreeCatalogEntry(entry, NULL);
2488 }
2490 }
2491
2492 } else if (type == SGML_CATA_CATALOG) {
2493 if (super) {
2494 xmlCatalogEntryPtr entry;
2495
2496 entry = xmlNewCatalogEntry(type, sysid, NULL, NULL,
2497 XML_CATA_PREFER_NONE, NULL);
2498 res = xmlHashAddEntry(catal->sgml, sysid, entry);
2499 if (res < 0) {
2500 xmlFreeCatalogEntry(entry, NULL);
2501 }
2502 } else {
2504
2505 filename = xmlBuildURI(sysid, base);
2506 if (filename != NULL) {
2507 xmlExpandCatalog(catal, (const char *)filename);
2509 }
2510 }
2511 }
2512 /*
2513 * drop anything else we won't handle it
2514 */
2515 if (name != NULL)
2516 xmlFree(name);
2517 if (sysid != NULL)
2518 xmlFree(sysid);
2519 }
2520 }
2521 if (base != NULL)
2522 xmlFree(base);
2523 if (cur == NULL)
2524 return(-1);
2525 return(0);
2526}
2527
2528/************************************************************************
2529 * *
2530 * SGML Catalog handling *
2531 * *
2532 ************************************************************************/
2533
2543static const xmlChar *
2544xmlCatalogGetSGMLPublic(xmlHashTablePtr catal, const xmlChar *pubID) {
2545 xmlCatalogEntryPtr entry;
2546 xmlChar *normid;
2547
2548 if (catal == NULL)
2549 return(NULL);
2550
2551 normid = xmlCatalogNormalizePublic(pubID);
2552 if (normid != NULL)
2553 pubID = (*normid != 0 ? normid : NULL);
2554
2555 entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, pubID);
2556 if (entry == NULL) {
2557 if (normid != NULL)
2558 xmlFree(normid);
2559 return(NULL);
2560 }
2561 if (entry->type == SGML_CATA_PUBLIC) {
2562 if (normid != NULL)
2563 xmlFree(normid);
2564 return(entry->URL);
2565 }
2566 if (normid != NULL)
2567 xmlFree(normid);
2568 return(NULL);
2569}
2570
2580static const xmlChar *
2581xmlCatalogGetSGMLSystem(xmlHashTablePtr catal, const xmlChar *sysID) {
2582 xmlCatalogEntryPtr entry;
2583
2584 if (catal == NULL)
2585 return(NULL);
2586
2587 entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, sysID);
2588 if (entry == NULL)
2589 return(NULL);
2590 if (entry->type == SGML_CATA_SYSTEM)
2591 return(entry->URL);
2592 return(NULL);
2593}
2594
2605static const xmlChar *
2606xmlCatalogSGMLResolve(xmlCatalogPtr catal, const xmlChar *pubID,
2607 const xmlChar *sysID) {
2608 const xmlChar *ret = NULL;
2609
2610 if (catal->sgml == NULL)
2611 return(NULL);
2612
2613 if (pubID != NULL)
2614 ret = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
2615 if (ret != NULL)
2616 return(ret);
2617 if (sysID != NULL)
2618 ret = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
2619 if (ret != NULL)
2620 return(ret);
2621 return(NULL);
2622}
2623
2624/************************************************************************
2625 * *
2626 * Specific Public interfaces *
2627 * *
2628 ************************************************************************/
2629
2640xmlCatalogPtr
2641xmlLoadSGMLSuperCatalog(const char *filename)
2642{
2644 xmlCatalogPtr catal;
2645 int ret;
2646
2647 content = xmlLoadFileContent(filename);
2648 if (content == NULL)
2649 return(NULL);
2650
2651 catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
2652 if (catal == NULL) {
2654 return(NULL);
2655 }
2656
2657 ret = xmlParseSGMLCatalog(catal, content, filename, 1);
2659 if (ret < 0) {
2660 xmlFreeCatalog(catal);
2661 return(NULL);
2662 }
2663 return (catal);
2664}
2665
2677xmlCatalogPtr
2678xmlLoadACatalog(const char *filename)
2679{
2681 xmlChar *first;
2682 xmlCatalogPtr catal;
2683 int ret;
2684
2685 content = xmlLoadFileContent(filename);
2686 if (content == NULL)
2687 return(NULL);
2688
2689
2690 first = content;
2691
2692 while ((*first != 0) && (*first != '-') && (*first != '<') &&
2693 (!(((*first >= 'A') && (*first <= 'Z')) ||
2694 ((*first >= 'a') && (*first <= 'z')))))
2695 first++;
2696
2697 if (*first != '<') {
2698 catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
2699 if (catal == NULL) {
2701 return(NULL);
2702 }
2703 ret = xmlParseSGMLCatalog(catal, content, filename, 0);
2704 if (ret < 0) {
2705 xmlFreeCatalog(catal);
2707 return(NULL);
2708 }
2709 } else {
2710 catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
2711 if (catal == NULL) {
2713 return(NULL);
2714 }
2715 catal->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
2716 NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
2717 }
2719 return (catal);
2720}
2721
2732static int
2733xmlExpandCatalog(xmlCatalogPtr catal, const char *filename)
2734{
2735 int ret;
2736
2737 if ((catal == NULL) || (filename == NULL))
2738 return(-1);
2739
2740
2741 if (catal->type == XML_SGML_CATALOG_TYPE) {
2743
2744 content = xmlLoadFileContent(filename);
2745 if (content == NULL)
2746 return(-1);
2747
2748 ret = xmlParseSGMLCatalog(catal, content, filename, 0);
2749 if (ret < 0) {
2751 return(-1);
2752 }
2754 } else {
2755 xmlCatalogEntryPtr tmp, cur;
2756 tmp = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
2757 NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
2758
2759 cur = catal->xml;
2760 if (cur == NULL) {
2761 catal->xml = tmp;
2762 } else {
2763 while (cur->next != NULL) cur = cur->next;
2764 cur->next = tmp;
2765 }
2766 }
2767 return (0);
2768}
2769
2780xmlChar *
2781xmlACatalogResolveSystem(xmlCatalogPtr catal, const xmlChar *sysID) {
2782 xmlChar *ret = NULL;
2783
2784 if ((sysID == NULL) || (catal == NULL))
2785 return(NULL);
2786
2787 if (xmlDebugCatalogs)
2789 "Resolve sysID %s\n", sysID);
2790
2791 if (catal->type == XML_XML_CATALOG_TYPE) {
2792 ret = xmlCatalogListXMLResolve(catal->xml, NULL, sysID);
2793 if (ret == XML_CATAL_BREAK)
2794 ret = NULL;
2795 } else {
2796 const xmlChar *sgml;
2797
2798 sgml = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
2799 if (sgml != NULL)
2800 ret = xmlStrdup(sgml);
2801 }
2802 return(ret);
2803}
2804
2815xmlChar *
2816xmlACatalogResolvePublic(xmlCatalogPtr catal, const xmlChar *pubID) {
2817 xmlChar *ret = NULL;
2818
2819 if ((pubID == NULL) || (catal == NULL))
2820 return(NULL);
2821
2822 if (xmlDebugCatalogs)
2824 "Resolve pubID %s\n", pubID);
2825
2826 if (catal->type == XML_XML_CATALOG_TYPE) {
2827 ret = xmlCatalogListXMLResolve(catal->xml, pubID, NULL);
2828 if (ret == XML_CATAL_BREAK)
2829 ret = NULL;
2830 } else {
2831 const xmlChar *sgml;
2832
2833 sgml = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
2834 if (sgml != NULL)
2835 ret = xmlStrdup(sgml);
2836 }
2837 return(ret);
2838}
2839
2851xmlChar *
2852xmlACatalogResolve(xmlCatalogPtr catal, const xmlChar * pubID,
2853 const xmlChar * sysID)
2854{
2855 xmlChar *ret = NULL;
2856
2857 if (((pubID == NULL) && (sysID == NULL)) || (catal == NULL))
2858 return (NULL);
2859
2860 if (xmlDebugCatalogs) {
2861 if ((pubID != NULL) && (sysID != NULL)) {
2863 "Resolve: pubID %s sysID %s\n", pubID, sysID);
2864 } else if (pubID != NULL) {
2866 "Resolve: pubID %s\n", pubID);
2867 } else {
2869 "Resolve: sysID %s\n", sysID);
2870 }
2871 }
2872
2873 if (catal->type == XML_XML_CATALOG_TYPE) {
2874 ret = xmlCatalogListXMLResolve(catal->xml, pubID, sysID);
2875 if (ret == XML_CATAL_BREAK)
2876 ret = NULL;
2877 } else {
2878 const xmlChar *sgml;
2879
2880 sgml = xmlCatalogSGMLResolve(catal, pubID, sysID);
2881 if (sgml != NULL)
2882 ret = xmlStrdup(sgml);
2883 }
2884 return (ret);
2885}
2886
2897xmlChar *
2898xmlACatalogResolveURI(xmlCatalogPtr catal, const xmlChar *URI) {
2899 xmlChar *ret = NULL;
2900
2901 if ((URI == NULL) || (catal == NULL))
2902 return(NULL);
2903
2904 if (xmlDebugCatalogs)
2906 "Resolve URI %s\n", URI);
2907
2908 if (catal->type == XML_XML_CATALOG_TYPE) {
2909 ret = xmlCatalogListXMLResolveURI(catal->xml, URI);
2910 if (ret == XML_CATAL_BREAK)
2911 ret = NULL;
2912 } else {
2913 const xmlChar *sgml;
2914
2915 sgml = xmlCatalogSGMLResolve(catal, NULL, URI);
2916 if (sgml != NULL)
2917 ret = xmlStrdup(sgml);
2918 }
2919 return(ret);
2920}
2921
2922#ifdef LIBXML_OUTPUT_ENABLED
2930void
2931xmlACatalogDump(xmlCatalogPtr catal, FILE *out) {
2932 if ((out == NULL) || (catal == NULL))
2933 return;
2934
2935 if (catal->type == XML_XML_CATALOG_TYPE) {
2936 xmlDumpXMLCatalog(out, catal->xml);
2937 } else {
2938 xmlHashScan(catal->sgml, xmlCatalogDumpEntry, out);
2939 }
2940}
2941#endif /* LIBXML_OUTPUT_ENABLED */
2942
2955int
2956xmlACatalogAdd(xmlCatalogPtr catal, const xmlChar * type,
2957 const xmlChar * orig, const xmlChar * replace)
2958{
2959 int res = -1;
2960
2961 if (catal == NULL)
2962 return(-1);
2963
2964 if (catal->type == XML_XML_CATALOG_TYPE) {
2965 res = xmlAddXMLCatalog(catal->xml, type, orig, replace);
2966 } else {
2967 xmlCatalogEntryType cattype;
2968
2969 cattype = xmlGetSGMLCatalogEntryType(type);
2970 if (cattype != XML_CATA_NONE) {
2971 xmlCatalogEntryPtr entry;
2972
2973 entry = xmlNewCatalogEntry(cattype, orig, replace, NULL,
2974 XML_CATA_PREFER_NONE, NULL);
2975 if (catal->sgml == NULL)
2976 catal->sgml = xmlHashCreate(10);
2977 res = xmlHashAddEntry(catal->sgml, orig, entry);
2978 }
2979 }
2980 return (res);
2981}
2982
2992int
2993xmlACatalogRemove(xmlCatalogPtr catal, const xmlChar *value) {
2994 int res = -1;
2995
2996 if ((catal == NULL) || (value == NULL))
2997 return(-1);
2998
2999 if (catal->type == XML_XML_CATALOG_TYPE) {
3000 res = xmlDelXMLCatalog(catal->xml, value);
3001 } else {
3002 res = xmlHashRemoveEntry(catal->sgml, value, xmlFreeCatalogEntry);
3003 if (res == 0)
3004 res = 1;
3005 }
3006 return(res);
3007}
3008
3017xmlCatalogPtr
3018xmlNewCatalog(int sgml) {
3019 xmlCatalogPtr catal = NULL;
3020
3021 if (sgml) {
3022 catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE,
3023 xmlCatalogDefaultPrefer);
3024 if ((catal != NULL) && (catal->sgml == NULL))
3025 catal->sgml = xmlHashCreate(10);
3026 } else
3027 catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
3028 xmlCatalogDefaultPrefer);
3029 return(catal);
3030}
3031
3040int
3041xmlCatalogIsEmpty(xmlCatalogPtr catal) {
3042 if (catal == NULL)
3043 return(-1);
3044
3045 if (catal->type == XML_XML_CATALOG_TYPE) {
3046 if (catal->xml == NULL)
3047 return(1);
3048 if ((catal->xml->type != XML_CATA_CATALOG) &&
3049 (catal->xml->type != XML_CATA_BROKEN_CATALOG))
3050 return(-1);
3051 if (catal->xml->children == NULL)
3052 return(1);
3053 return(0);
3054 } else {
3055 int res;
3056
3057 if (catal->sgml == NULL)
3058 return(1);
3059 res = xmlHashSize(catal->sgml);
3060 if (res == 0)
3061 return(1);
3062 if (res < 0)
3063 return(-1);
3064 }
3065 return(0);
3066}
3067
3068/************************************************************************
3069 * *
3070 * Public interfaces manipulating the global shared default catalog *
3071 * *
3072 ************************************************************************/
3073
3082static void
3083xmlInitializeCatalogData(void) {
3084 if (xmlCatalogInitialized != 0)
3085 return;
3086
3087 if (getenv("XML_DEBUG_CATALOG"))
3088 xmlDebugCatalogs = 1;
3089 xmlCatalogMutex = xmlNewRMutex();
3090
3091 xmlCatalogInitialized = 1;
3092}
3100void
3101xmlInitializeCatalog(void) {
3102 if (xmlCatalogInitialized != 0)
3103 return;
3104
3105 xmlInitializeCatalogData();
3106 xmlRMutexLock(xmlCatalogMutex);
3107
3108 if (getenv("XML_DEBUG_CATALOG"))
3109 xmlDebugCatalogs = 1;
3110
3111 if (xmlDefaultCatalog == NULL) {
3112 const char *catalogs;
3113 char *path;
3114 const char *cur, *paths;
3115 xmlCatalogPtr catal;
3116 xmlCatalogEntryPtr *nextent;
3117
3118 catalogs = (const char *) getenv("XML_CATALOG_FILES");
3119 if (catalogs == NULL)
3120#if defined(_WIN32) && defined(_MSC_VER)
3121 {
3122 void* hmodule;
3123 hmodule = GetModuleHandleA("libxml2.dll");
3124 if (hmodule == NULL)
3126 if (hmodule != NULL) {
3127 char buf[256];
3128 unsigned long len = GetModuleFileNameA(hmodule, buf, 255);
3129 if (len != 0) {
3130 char* p = &(buf[len]);
3131 while (*p != '\\' && p > buf)
3132 p--;
3133 if (p != buf) {
3134 xmlChar* uri;
3135 strncpy(p, "\\..\\etc\\catalog", 255 - (p - buf));
3136 uri = xmlCanonicPath((const xmlChar*)buf);
3137 if (uri != NULL) {
3139 xmlFree(uri);
3140 }
3141 }
3142 }
3143 }
3144 catalogs = XML_XML_DEFAULT_CATALOG;
3145 }
3146#else
3147 catalogs = XML_XML_DEFAULT_CATALOG;
3148#endif
3149
3150 catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
3151 xmlCatalogDefaultPrefer);
3152 if (catal != NULL) {
3153 /* the XML_CATALOG_FILES envvar is allowed to contain a
3154 space-separated list of entries. */
3155 cur = catalogs;
3156 nextent = &catal->xml;
3157 while (*cur != '\0') {
3158 while (xmlIsBlank_ch(*cur))
3159 cur++;
3160 if (*cur != 0) {
3161 paths = cur;
3162 while ((*cur != 0) && (!xmlIsBlank_ch(*cur)))
3163 cur++;
3164 path = (char *) xmlStrndup((const xmlChar *)paths, cur - paths);
3165 if (path != NULL) {
3166 *nextent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
3167 NULL, BAD_CAST path, xmlCatalogDefaultPrefer, NULL);
3168 if (*nextent != NULL)
3169 nextent = &((*nextent)->next);
3170 xmlFree(path);
3171 }
3172 }
3173 }
3174 xmlDefaultCatalog = catal;
3175 }
3176 }
3177
3178 xmlRMutexUnlock(xmlCatalogMutex);
3179}
3180
3181
3193int
3194xmlLoadCatalog(const char *filename)
3195{
3196 int ret;
3197 xmlCatalogPtr catal;
3198
3199 if (!xmlCatalogInitialized)
3200 xmlInitializeCatalogData();
3201
3202 xmlRMutexLock(xmlCatalogMutex);
3203
3204 if (xmlDefaultCatalog == NULL) {
3205 catal = xmlLoadACatalog(filename);
3206 if (catal == NULL) {
3207 xmlRMutexUnlock(xmlCatalogMutex);
3208 return(-1);
3209 }
3210
3211 xmlDefaultCatalog = catal;
3212 xmlRMutexUnlock(xmlCatalogMutex);
3213 return(0);
3214 }
3215
3216 ret = xmlExpandCatalog(xmlDefaultCatalog, filename);
3217 xmlRMutexUnlock(xmlCatalogMutex);
3218 return(ret);
3219}
3220
3230void
3231xmlLoadCatalogs(const char *pathss) {
3232 const char *cur;
3233 const char *paths;
3234 xmlChar *path;
3235#ifdef _WIN32
3236 int i, iLen;
3237#endif
3238
3239 if (pathss == NULL)
3240 return;
3241
3242 cur = pathss;
3243 while (*cur != 0) {
3244 while (xmlIsBlank_ch(*cur)) cur++;
3245 if (*cur != 0) {
3246 paths = cur;
3247 while ((*cur != 0) && (*cur != PATH_SEPARATOR) && (!xmlIsBlank_ch(*cur)))
3248 cur++;
3249 path = xmlStrndup((const xmlChar *)paths, cur - paths);
3250 if (path != NULL) {
3251#ifdef _WIN32
3252 iLen = strlen((const char*)path);
3253 for(i = 0; i < iLen; i++) {
3254 if(path[i] == '\\') {
3255 path[i] = '/';
3256 }
3257 }
3258#endif
3259 xmlLoadCatalog((const char *) path);
3260 xmlFree(path);
3261 }
3262 }
3263 while (*cur == PATH_SEPARATOR)
3264 cur++;
3265 }
3266}
3267
3273void
3274xmlCatalogCleanup(void) {
3275 if (xmlCatalogInitialized == 0)
3276 return;
3277
3278 xmlRMutexLock(xmlCatalogMutex);
3279 if (xmlDebugCatalogs)
3281 "Catalogs cleanup\n");
3282 if (xmlCatalogXMLFiles != NULL)
3283 xmlHashFree(xmlCatalogXMLFiles, xmlFreeCatalogHashEntryList);
3284 xmlCatalogXMLFiles = NULL;
3285 if (xmlDefaultCatalog != NULL)
3286 xmlFreeCatalog(xmlDefaultCatalog);
3287 xmlDefaultCatalog = NULL;
3288 xmlDebugCatalogs = 0;
3289 xmlCatalogInitialized = 0;
3290 xmlRMutexUnlock(xmlCatalogMutex);
3291 xmlFreeRMutex(xmlCatalogMutex);
3292}
3293
3303xmlChar *
3304xmlCatalogResolveSystem(const xmlChar *sysID) {
3305 xmlChar *ret;
3306
3307 if (!xmlCatalogInitialized)
3308 xmlInitializeCatalog();
3309
3310 ret = xmlACatalogResolveSystem(xmlDefaultCatalog, sysID);
3311 return(ret);
3312}
3313
3323xmlChar *
3324xmlCatalogResolvePublic(const xmlChar *pubID) {
3325 xmlChar *ret;
3326
3327 if (!xmlCatalogInitialized)
3328 xmlInitializeCatalog();
3329
3330 ret = xmlACatalogResolvePublic(xmlDefaultCatalog, pubID);
3331 return(ret);
3332}
3333
3344xmlChar *
3345xmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) {
3346 xmlChar *ret;
3347
3348 if (!xmlCatalogInitialized)
3349 xmlInitializeCatalog();
3350
3351 ret = xmlACatalogResolve(xmlDefaultCatalog, pubID, sysID);
3352 return(ret);
3353}
3354
3364xmlChar *
3365xmlCatalogResolveURI(const xmlChar *URI) {
3366 xmlChar *ret;
3367
3368 if (!xmlCatalogInitialized)
3369 xmlInitializeCatalog();
3370
3371 ret = xmlACatalogResolveURI(xmlDefaultCatalog, URI);
3372 return(ret);
3373}
3374
3375#ifdef LIBXML_OUTPUT_ENABLED
3382void
3383xmlCatalogDump(FILE *out) {
3384 if (out == NULL)
3385 return;
3386
3387 if (!xmlCatalogInitialized)
3388 xmlInitializeCatalog();
3389
3390 xmlACatalogDump(xmlDefaultCatalog, out);
3391}
3392#endif /* LIBXML_OUTPUT_ENABLED */
3393
3407int
3408xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) {
3409 int res = -1;
3410
3411 if (!xmlCatalogInitialized)
3412 xmlInitializeCatalogData();
3413
3414 xmlRMutexLock(xmlCatalogMutex);
3415 /*
3416 * Specific case where one want to override the default catalog
3417 * put in place by xmlInitializeCatalog();
3418 */
3419 if ((xmlDefaultCatalog == NULL) &&
3420 (xmlStrEqual(type, BAD_CAST "catalog"))) {
3421 xmlDefaultCatalog = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
3422 xmlCatalogDefaultPrefer);
3423 if (xmlDefaultCatalog != NULL) {
3424 xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
3425 orig, NULL, xmlCatalogDefaultPrefer, NULL);
3426 }
3427 xmlRMutexUnlock(xmlCatalogMutex);
3428 return(0);
3429 }
3430
3431 res = xmlACatalogAdd(xmlDefaultCatalog, type, orig, replace);
3432 xmlRMutexUnlock(xmlCatalogMutex);
3433 return(res);
3434}
3435
3444int
3445xmlCatalogRemove(const xmlChar *value) {
3446 int res;
3447
3448 if (!xmlCatalogInitialized)
3449 xmlInitializeCatalog();
3450
3451 xmlRMutexLock(xmlCatalogMutex);
3452 res = xmlACatalogRemove(xmlDefaultCatalog, value);
3453 xmlRMutexUnlock(xmlCatalogMutex);
3454 return(res);
3455}
3456
3464int
3465xmlCatalogConvert(void) {
3466 int res = -1;
3467
3468 if (!xmlCatalogInitialized)
3469 xmlInitializeCatalog();
3470
3471 xmlRMutexLock(xmlCatalogMutex);
3472 res = xmlConvertSGMLCatalog(xmlDefaultCatalog);
3473 xmlRMutexUnlock(xmlCatalogMutex);
3474 return(res);
3475}
3476
3477/************************************************************************
3478 * *
3479 * Public interface manipulating the common preferences *
3480 * *
3481 ************************************************************************/
3482
3491xmlCatalogAllow
3492xmlCatalogGetDefaults(void) {
3493 return(xmlCatalogDefaultAllow);
3494}
3495
3503void
3504xmlCatalogSetDefaults(xmlCatalogAllow allow) {
3505 if (xmlDebugCatalogs) {
3506 switch (allow) {
3507 case XML_CATA_ALLOW_NONE:
3509 "Disabling catalog usage\n");
3510 break;
3511 case XML_CATA_ALLOW_GLOBAL:
3513 "Allowing only global catalogs\n");
3514 break;
3515 case XML_CATA_ALLOW_DOCUMENT:
3517 "Allowing only catalogs from the document\n");
3518 break;
3519 case XML_CATA_ALLOW_ALL:
3521 "Allowing all catalogs\n");
3522 break;
3523 }
3524 }
3525 xmlCatalogDefaultAllow = allow;
3526}
3527
3538xmlCatalogPrefer
3539xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) {
3540 xmlCatalogPrefer ret = xmlCatalogDefaultPrefer;
3541
3542 if (prefer == XML_CATA_PREFER_NONE)
3543 return(ret);
3544
3545 if (xmlDebugCatalogs) {
3546 switch (prefer) {
3547 case XML_CATA_PREFER_PUBLIC:
3549 "Setting catalog preference to PUBLIC\n");
3550 break;
3551 case XML_CATA_PREFER_SYSTEM:
3553 "Setting catalog preference to SYSTEM\n");
3554 break;
3555 default:
3556 return(ret);
3557 }
3558 }
3559 xmlCatalogDefaultPrefer = prefer;
3560 return(ret);
3561}
3562
3572int
3573xmlCatalogSetDebug(int level) {
3574 int ret = xmlDebugCatalogs;
3575
3576 if (level <= 0)
3577 xmlDebugCatalogs = 0;
3578 else
3579 xmlDebugCatalogs = level;
3580 return(ret);
3581}
3582
3583/************************************************************************
3584 * *
3585 * Minimal interfaces used for per-document catalogs by the parser *
3586 * *
3587 ************************************************************************/
3588
3595void
3596xmlCatalogFreeLocal(void *catalogs) {
3597 xmlCatalogEntryPtr catal;
3598
3599 if (!xmlCatalogInitialized)
3600 xmlInitializeCatalog();
3601
3602 catal = (xmlCatalogEntryPtr) catalogs;
3603 if (catal != NULL)
3604 xmlFreeCatalogEntryList(catal);
3605}
3606
3607
3617void *
3618xmlCatalogAddLocal(void *catalogs, const xmlChar *URL) {
3619 xmlCatalogEntryPtr catal, add;
3620
3621 if (!xmlCatalogInitialized)
3622 xmlInitializeCatalog();
3623
3624 if (URL == NULL)
3625 return(catalogs);
3626
3627 if (xmlDebugCatalogs)
3629 "Adding document catalog %s\n", URL);
3630
3631 add = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, URL, NULL,
3632 xmlCatalogDefaultPrefer, NULL);
3633 if (add == NULL)
3634 return(catalogs);
3635
3636 catal = (xmlCatalogEntryPtr) catalogs;
3637 if (catal == NULL)
3638 return((void *) add);
3639
3640 while (catal->next != NULL)
3641 catal = catal->next;
3642 catal->next = add;
3643 return(catalogs);
3644}
3645
3658xmlChar *
3659xmlCatalogLocalResolve(void *catalogs, const xmlChar *pubID,
3660 const xmlChar *sysID) {
3661 xmlCatalogEntryPtr catal;
3662 xmlChar *ret;
3663
3664 if (!xmlCatalogInitialized)
3665 xmlInitializeCatalog();
3666
3667 if ((pubID == NULL) && (sysID == NULL))
3668 return(NULL);
3669
3670 if (xmlDebugCatalogs) {
3671 if ((pubID != NULL) && (sysID != NULL)) {
3673 "Local Resolve: pubID %s sysID %s\n", pubID, sysID);
3674 } else if (pubID != NULL) {
3676 "Local Resolve: pubID %s\n", pubID);
3677 } else {
3679 "Local Resolve: sysID %s\n", sysID);
3680 }
3681 }
3682
3683 catal = (xmlCatalogEntryPtr) catalogs;
3684 if (catal == NULL)
3685 return(NULL);
3686 ret = xmlCatalogListXMLResolve(catal, pubID, sysID);
3687 if ((ret != NULL) && (ret != XML_CATAL_BREAK))
3688 return(ret);
3689 return(NULL);
3690}
3691
3703xmlChar *
3704xmlCatalogLocalResolveURI(void *catalogs, const xmlChar *URI) {
3705 xmlCatalogEntryPtr catal;
3706 xmlChar *ret;
3707
3708 if (!xmlCatalogInitialized)
3709 xmlInitializeCatalog();
3710
3711 if (URI == NULL)
3712 return(NULL);
3713
3714 if (xmlDebugCatalogs)
3716 "Resolve URI %s\n", URI);
3717
3718 catal = (xmlCatalogEntryPtr) catalogs;
3719 if (catal == NULL)
3720 return(NULL);
3721 ret = xmlCatalogListXMLResolveURI(catal, URI);
3722 if ((ret != NULL) && (ret != XML_CATAL_BREAK))
3723 return(ret);
3724 return(NULL);
3725}
3726
3727/************************************************************************
3728 * *
3729 * Deprecated interfaces *
3730 * *
3731 ************************************************************************/
3741const xmlChar *
3742xmlCatalogGetSystem(const xmlChar *sysID) {
3743 xmlChar *ret;
3744 static xmlChar result[1000];
3745 static int msg = 0;
3746
3747 if (!xmlCatalogInitialized)
3748 xmlInitializeCatalog();
3749
3750 if (msg == 0) {
3752 "Use of deprecated xmlCatalogGetSystem() call\n");
3753 msg++;
3754 }
3755
3756 if (sysID == NULL)
3757 return(NULL);
3758
3759 /*
3760 * Check first the XML catalogs
3761 */
3762 if (xmlDefaultCatalog != NULL) {
3763 ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, NULL, sysID);
3764 if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
3765 snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
3766 result[sizeof(result) - 1] = 0;
3767 return(result);
3768 }
3769 }
3770
3771 if (xmlDefaultCatalog != NULL)
3772 return(xmlCatalogGetSGMLSystem(xmlDefaultCatalog->sgml, sysID));
3773 return(NULL);
3774}
3775
3785const xmlChar *
3786xmlCatalogGetPublic(const xmlChar *pubID) {
3787 xmlChar *ret;
3788 static xmlChar result[1000];
3789 static int msg = 0;
3790
3791 if (!xmlCatalogInitialized)
3792 xmlInitializeCatalog();
3793
3794 if (msg == 0) {
3796 "Use of deprecated xmlCatalogGetPublic() call\n");
3797 msg++;
3798 }
3799
3800 if (pubID == NULL)
3801 return(NULL);
3802
3803 /*
3804 * Check first the XML catalogs
3805 */
3806 if (xmlDefaultCatalog != NULL) {
3807 ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, pubID, NULL);
3808 if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
3809 snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
3810 result[sizeof(result) - 1] = 0;
3811 return(result);
3812 }
3813 }
3814
3815 if (xmlDefaultCatalog != NULL)
3816 return(xmlCatalogGetSGMLPublic(xmlDefaultCatalog->sgml, pubID));
3817 return(NULL);
3818}
3819
3820#endif /* LIBXML_CATALOG_ENABLED */
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define stat
Definition: acwin.h:99
#define read
Definition: acwin.h:96
#define O_RDONLY
Definition: acwin.h:108
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
#define ok(value,...)
Definition: atltest.h:57
#define msg(x)
Definition: auth_time.c:54
int xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input)
Definition: buf.c:1094
#define SEEK_END
Definition: cabinet.c:29
#define xmlIsBlank_ch(c)
Definition: chvalid.h:88
#define NULL
Definition: types.h:112
#define SKIP_BLANKS
Definition: pattern.c:1175
#define SKIP(val)
Definition: pattern.c:1171
content
Definition: atl_ax.c:994
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
r parent
Definition: btrfs.c:3010
void dealloc(int i, int no_throw)
Definition: ehthrow.cxx:33
@ XML_CHAR_ENCODING_NONE
Definition: encoding.h:58
#define NEXT(n, i)
FxCollectionEntry * cur
#define RAW(x)
Definition: genincdata.c:42
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLboolean GLuint group
Definition: glext.h:11120
const GLint * first
Definition: glext.h:5794
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLsizei const GLuint * paths
Definition: glext.h:11717
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
@ extra
Definition: id3.c:95
#define EOF
Definition: stdio.h:24
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define SEEK_SET
Definition: jmemansi.c:26
#define c
Definition: ke_i.h:80
#define SYSCONFDIR
Definition: libxml.h:35
#define error(str)
Definition: mkdosfs.c:1605
static HMODULE hmodule
Definition: rasapi.c:29
const char * uri
Definition: sec_mgr.c:1588
XMLPUBFUN xmlParserInputPtr XMLCALL xmlNewInputStream(xmlParserCtxtPtr ctxt)
#define XML_MAX_NAMELEN
#define IS_DIGIT(c)
#define IS_PUBIDCHAR_CH(c)
XMLPUBFUN int XMLCALL inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
Definition: parser.c:1745
#define IS_LETTER(c)
#define IS_BLANK_CH(c)
static unsigned __int64 next
Definition: rand_nt.c:6
static FILE * out
Definition: regtests2xml.c:44
INT replace(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], DWORD dwFlags, BOOL *doMore)
Definition: replace.c:47
XMLPUBVAR xmlMallocFunc xmlMallocAtomic
Definition: globals.h:249
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBVAR void * xmlGenericErrorContext
Definition: globals.h:353
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:250
XMLPUBVAR xmlSAXHandlerV1 xmlDefaultSAXHandler
Definition: globals.h:312
XMLPUBVAR xmlGenericErrorFunc xmlGenericError
Definition: globals.h:337
XMLPUBFUN void XMLCALL xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f)
Definition: hash.c:322
XMLPUBFUN void *XMLCALL xmlHashLookup(xmlHashTablePtr table, const xmlChar *name)
Definition: hash.c:461
XMLPUBFUN xmlHashTablePtr XMLCALL xmlHashCreate(int size)
Definition: hash.c:176
XMLPUBFUN int XMLCALL xmlHashSize(xmlHashTablePtr table)
Definition: hash.c:1034
XMLPUBFUN int XMLCALL xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata)
Definition: hash.c:389
XMLPUBFUN int XMLCALL xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name, xmlHashDeallocator f)
Definition: hash.c:1052
XMLPUBFUN void XMLCALL xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data)
Definition: hash.c:859
XMLPUBFUN void XMLCALL xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
XMLPUBFUN int XMLCALL xmlParseDocument(xmlParserCtxtPtr ctxt)
Definition: parser.c:10697
XMLPUBFUN xmlParserCtxtPtr XMLCALL xmlNewParserCtxt(void)
XMLPUBFUN xmlNodePtr XMLCALL xmlAddChild(xmlNodePtr parent, xmlNodePtr cur)
XMLPUBFUN xmlDtdPtr XMLCALL xmlNewDtd(xmlDocPtr doc, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID)
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement(const xmlDoc *doc)
XMLPUBFUN void XMLCALL xmlFreeDoc(xmlDocPtr cur)
XMLPUBFUN xmlChar *XMLCALL xmlGetProp(const xmlNode *node, const xmlChar *name)
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name, const xmlChar *content)
xmlOutputBuffer * xmlOutputBufferPtr
Definition: tree.h:32
XMLPUBFUN xmlDocPtr XMLCALL xmlNewDoc(const xmlChar *version)
XMLPUBFUN xmlChar *XMLCALL xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace)
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href)
XMLPUBFUN xmlChar *XMLCALL xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur)
#define XML_XML_NAMESPACE
Definition: tree.h:140
XMLPUBFUN void XMLCALL xmlFreeNs(xmlNsPtr cur)
XMLPUBFUN xmlNsPtr XMLCALL xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix)
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
Definition: tree.h:551
Definition: tree.h:406
Definition: tree.h:489
xmlNs * nsDef
Definition: tree.h:504
Definition: tree.h:389
char * directory
Definition: parser.h:226
int wellFormed
Definition: parser.h:188
int loadsubset
Definition: parser.h:258
int dictNames
Definition: parser.h:292
xmlDocPtr myDoc
Definition: parser.h:187
int pedantic
Definition: parser.h:255
int validate
Definition: parser.h:220
const char * filename
Definition: parser.h:56
xmlParserInputBufferPtr buf
Definition: parser.h:54
errorSAXFunc error
Definition: parser.h:783
struct define * next
Definition: compiler.c:65
Definition: fci.c:127
Definition: name.c:39
Definition: mxnamespace.c:45
Definition: stat.h:55
XMLPUBFUN void XMLCALL xmlRMutexLock(xmlRMutexPtr tok)
Definition: threads.c:333
XMLPUBFUN void XMLCALL xmlFreeRMutex(xmlRMutexPtr tok)
Definition: threads.c:309
XMLPUBFUN xmlRMutexPtr XMLCALL xmlNewRMutex(void)
Definition: threads.c:276
XMLPUBFUN int XMLCALL xmlGetThreadId(void)
Definition: threads.c:750
XMLPUBFUN void XMLCALL xmlRMutexUnlock(xmlRMutexPtr tok)
Definition: threads.c:377
#define __stdcall
Definition: typedefs.h:25
Definition: dlist.c:348
Definition: pdh_main.c:94
XMLPUBFUN xmlChar *XMLCALL xmlCanonicPath(const xmlChar *path)
Definition: uri.c:2380
XMLPUBFUN xmlChar *XMLCALL xmlBuildURI(const xmlChar *URI, const xmlChar *base)
Definition: uri.c:1892
int ret
#define snprintf
Definition: wintirpc.h:48
XMLPUBFUN char *XMLCALL xmlParserGetDirectory(const char *filename)
XMLPUBFUN void XMLCALL xmlFreeParserInputBuffer(xmlParserInputBufferPtr in)
XMLPUBFUN xmlParserInputBufferPtr XMLCALL xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc)
@ XML_ERR_ERROR
Definition: xmlerror.h:27
@ XML_FROM_CATALOG
Definition: xmlerror.h:57
@ XML_CATALOG_RECURSION
Definition: xmlerror.h:498
@ XML_CATALOG_PREFER_VALUE
Definition: xmlerror.h:496
@ XML_CATALOG_ENTRY_BROKEN
Definition: xmlerror.h:495
@ XML_CATALOG_NOT_CATALOG
Definition: xmlerror.h:497
@ XML_CATALOG_MISSING_ATTR
Definition: xmlerror.h:494
@ XML_ERR_NO_MEMORY
Definition: xmlerror.h:102
#define XML_XML_DEFAULT_CATALOG
Definition: xmllint.c:84
#define PATH_SEPARATOR
Definition: xmllint.c:205
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:42
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:524
XMLPUBFUN int XMLCALL xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len)
Definition: xmlstring.c:213
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:67
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:426
unsigned char xmlChar
Definition: xmlstring.h:28
#define LIBXML_ATTR_FORMAT(fmt, args)
Definition: xmlversion.h:486
#define const
Definition: zconf.h:233