ReactOS  0.4.15-dev-3303-g1ade494
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 #ifdef HAVE_SYS_TYPES_H
20 #include <sys/types.h>
21 #endif
22 #ifdef HAVE_SYS_STAT_H
23 #include <sys/stat.h>
24 #endif
25 #ifdef HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28 #ifdef HAVE_FCNTL_H
29 #include <fcntl.h>
30 #endif
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34 #include <string.h>
35 #include <libxml/xmlmemory.h>
36 #include <libxml/hash.h>
37 #include <libxml/uri.h>
38 #include <libxml/parserInternals.h>
39 #include <libxml/catalog.h>
40 #include <libxml/xmlerror.h>
41 #include <libxml/threads.h>
42 #include <libxml/globals.h>
43 
44 #include "buf.h"
45 
46 #define MAX_DELEGATE 50
47 #define MAX_CATAL_DEPTH 50
48 
49 #ifdef _WIN32
50 # define PATH_SEPARATOR ';'
51 #else
52 # define PATH_SEPARATOR ':'
53 #endif
54 
65 #define TODO \
66  xmlGenericError(xmlGenericErrorContext, \
67  "Unimplemented block at %s:%d\n", \
68  __FILE__, __LINE__);
69 
70 #define XML_URN_PUBID "urn:publicid:"
71 #define XML_CATAL_BREAK ((xmlChar *) -1)
72 #ifndef XML_XML_DEFAULT_CATALOG
73 #define XML_XML_DEFAULT_CATALOG "file:
74 #endif
75 #ifndef XML_SGML_DEFAULT_CATALOG
76 #define XML_SGML_DEFAULT_CATALOG "file:
77 #endif
78 
79 #if defined(_WIN32) && defined(_MSC_VER)
80 #undef XML_XML_DEFAULT_CATALOG
81 static char XML_XML_DEFAULT_CATALOG[256] = "file:///etc/xml/catalog";
82 #if defined(_WIN32_WCE)
83 /* Windows CE don't have a A variant */
84 #define GetModuleHandleA GetModuleHandle
85 #define GetModuleFileNameA GetModuleFileName
86 #else
87 #if !defined(_WINDOWS_)
88 void* __stdcall GetModuleHandleA(const char*);
89 unsigned long __stdcall GetModuleFileNameA(void*, char*, unsigned long);
90 #endif
91 #endif
92 #endif
93 
94 static xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID);
95 static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename);
96 
97 /************************************************************************
98  * *
99  * Types, all private *
100  * *
101  ************************************************************************/
102 
103 typedef enum {
104  XML_CATA_REMOVED = -1,
105  XML_CATA_NONE = 0,
106  XML_CATA_CATALOG,
107  XML_CATA_BROKEN_CATALOG,
108  XML_CATA_NEXT_CATALOG,
109  XML_CATA_GROUP,
110  XML_CATA_PUBLIC,
111  XML_CATA_SYSTEM,
112  XML_CATA_REWRITE_SYSTEM,
113  XML_CATA_DELEGATE_PUBLIC,
114  XML_CATA_DELEGATE_SYSTEM,
115  XML_CATA_URI,
116  XML_CATA_REWRITE_URI,
117  XML_CATA_DELEGATE_URI,
118  SGML_CATA_SYSTEM,
119  SGML_CATA_PUBLIC,
120  SGML_CATA_ENTITY,
121  SGML_CATA_PENTITY,
122  SGML_CATA_DOCTYPE,
123  SGML_CATA_LINKTYPE,
124  SGML_CATA_NOTATION,
125  SGML_CATA_DELEGATE,
126  SGML_CATA_BASE,
127  SGML_CATA_CATALOG,
128  SGML_CATA_DOCUMENT,
129  SGML_CATA_SGMLDECL
130 } xmlCatalogEntryType;
131 
132 typedef struct _xmlCatalogEntry xmlCatalogEntry;
133 typedef xmlCatalogEntry *xmlCatalogEntryPtr;
134 struct _xmlCatalogEntry {
135  struct _xmlCatalogEntry *next;
136  struct _xmlCatalogEntry *parent;
137  struct _xmlCatalogEntry *children;
138  xmlCatalogEntryType type;
139  xmlChar *name;
140  xmlChar *value;
141  xmlChar *URL; /* The expanded URL using the base */
142  xmlCatalogPrefer prefer;
143  int dealloc;
144  int depth;
145  struct _xmlCatalogEntry *group;
146 };
147 
148 typedef enum {
149  XML_XML_CATALOG_TYPE = 1,
150  XML_SGML_CATALOG_TYPE
151 } xmlCatalogType;
152 
153 #define XML_MAX_SGML_CATA_DEPTH 10
154 struct _xmlCatalog {
155  xmlCatalogType type; /* either XML or SGML */
156 
157  /*
158  * SGML Catalogs are stored as a simple hash table of catalog entries
159  * Catalog stack to check against overflows when building the
160  * SGML catalog
161  */
162  char *catalTab[XML_MAX_SGML_CATA_DEPTH]; /* stack of catals */
163  int catalNr; /* Number of current catal streams */
164  int catalMax; /* Max number of catal streams */
165  xmlHashTablePtr sgml;
166 
167  /*
168  * XML Catalogs are stored as a tree of Catalog entries
169  */
170  xmlCatalogPrefer prefer;
171  xmlCatalogEntryPtr xml;
172 };
173 
174 /************************************************************************
175  * *
176  * Global variables *
177  * *
178  ************************************************************************/
179 
180 /*
181  * Those are preferences
182  */
183 static int xmlDebugCatalogs = 0; /* used for debugging */
184 static xmlCatalogAllow xmlCatalogDefaultAllow = XML_CATA_ALLOW_ALL;
185 static xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_PUBLIC;
186 
187 /*
188  * Hash table containing all the trees of XML catalogs parsed by
189  * the application.
190  */
191 static xmlHashTablePtr xmlCatalogXMLFiles = NULL;
192 
193 /*
194  * The default catalog in use by the application
195  */
196 static xmlCatalogPtr xmlDefaultCatalog = NULL;
197 
198 /*
199  * A mutex for modifying the shared global catalog(s)
200  * xmlDefaultCatalog tree.
201  * It also protects xmlCatalogXMLFiles
202  * The core of this readers/writer scheme is in xmlFetchXMLCatalogFile()
203  */
204 static xmlRMutexPtr xmlCatalogMutex = NULL;
205 
206 /*
207  * Whether the catalog support was initialized.
208  */
209 static int xmlCatalogInitialized = 0;
210 
211 /************************************************************************
212  * *
213  * Catalog error handlers *
214  * *
215  ************************************************************************/
216 
223 static void
224 xmlCatalogErrMemory(const char *extra)
225 {
226  __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_CATALOG,
228  extra, NULL, NULL, 0, 0,
229  "Memory allocation failed : %s\n", extra);
230 }
231 
241 static void LIBXML_ATTR_FORMAT(4,0)
242 xmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error,
243  const char *msg, const xmlChar *str1, const xmlChar *str2,
244  const xmlChar *str3)
245 {
246  __xmlRaiseError(NULL, NULL, NULL, catal, node, XML_FROM_CATALOG,
247  error, XML_ERR_ERROR, NULL, 0,
248  (const char *) str1, (const char *) str2,
249  (const char *) str3, 0, 0,
250  msg, str1, str2, str3);
251 }
252 
253 
254 /************************************************************************
255  * *
256  * Allocation and Freeing *
257  * *
258  ************************************************************************/
259 
273 static xmlCatalogEntryPtr
274 xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
275  const xmlChar *value, const xmlChar *URL, xmlCatalogPrefer prefer,
276  xmlCatalogEntryPtr group) {
277  xmlCatalogEntryPtr ret;
278  xmlChar *normid = NULL;
279 
280  ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
281  if (ret == NULL) {
282  xmlCatalogErrMemory("allocating catalog entry");
283  return(NULL);
284  }
285  ret->next = NULL;
286  ret->parent = NULL;
287  ret->children = NULL;
288  ret->type = type;
289  if (type == XML_CATA_PUBLIC || type == XML_CATA_DELEGATE_PUBLIC) {
290  normid = xmlCatalogNormalizePublic(name);
291  if (normid != NULL)
292  name = (*normid != 0 ? normid : NULL);
293  }
294  if (name != NULL)
295  ret->name = xmlStrdup(name);
296  else
297  ret->name = NULL;
298  if (normid != NULL)
299  xmlFree(normid);
300  if (value != NULL)
301  ret->value = xmlStrdup(value);
302  else
303  ret->value = NULL;
304  if (URL == NULL)
305  URL = value;
306  if (URL != NULL)
307  ret->URL = xmlStrdup(URL);
308  else
309  ret->URL = NULL;
310  ret->prefer = prefer;
311  ret->dealloc = 0;
312  ret->depth = 0;
313  ret->group = group;
314  return(ret);
315 }
316 
317 static void
318 xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret);
319 
326 static void
327 xmlFreeCatalogEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
328  xmlCatalogEntryPtr ret = (xmlCatalogEntryPtr) payload;
329  if (ret == NULL)
330  return;
331  /*
332  * Entries stored in the file hash must be deallocated
333  * only by the file hash cleaner !
334  */
335  if (ret->dealloc == 1)
336  return;
337 
338  if (xmlDebugCatalogs) {
339  if (ret->name != NULL)
341  "Free catalog entry %s\n", ret->name);
342  else if (ret->value != NULL)
344  "Free catalog entry %s\n", ret->value);
345  else
347  "Free catalog entry\n");
348  }
349 
350  if (ret->name != NULL)
351  xmlFree(ret->name);
352  if (ret->value != NULL)
353  xmlFree(ret->value);
354  if (ret->URL != NULL)
355  xmlFree(ret->URL);
356  xmlFree(ret);
357 }
358 
365 static void
366 xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret) {
367  xmlCatalogEntryPtr next;
368 
369  while (ret != NULL) {
370  next = ret->next;
371  xmlFreeCatalogEntry(ret, NULL);
372  ret = next;
373  }
374 }
375 
383 static void
384 xmlFreeCatalogHashEntryList(void *payload,
385  const xmlChar *name ATTRIBUTE_UNUSED) {
386  xmlCatalogEntryPtr catal = (xmlCatalogEntryPtr) payload;
387  xmlCatalogEntryPtr children, next;
388 
389  if (catal == NULL)
390  return;
391 
392  children = catal->children;
393  while (children != NULL) {
394  next = children->next;
395  children->dealloc = 0;
396  children->children = NULL;
397  xmlFreeCatalogEntry(children, NULL);
398  children = next;
399  }
400  catal->dealloc = 0;
401  xmlFreeCatalogEntry(catal, NULL);
402 }
403 
414 static xmlCatalogPtr
415 xmlCreateNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) {
416  xmlCatalogPtr ret;
417 
418  ret = (xmlCatalogPtr) xmlMalloc(sizeof(xmlCatalog));
419  if (ret == NULL) {
420  xmlCatalogErrMemory("allocating catalog");
421  return(NULL);
422  }
423  memset(ret, 0, sizeof(xmlCatalog));
424  ret->type = type;
425  ret->catalNr = 0;
426  ret->catalMax = XML_MAX_SGML_CATA_DEPTH;
427  ret->prefer = prefer;
428  if (ret->type == XML_SGML_CATALOG_TYPE)
429  ret->sgml = xmlHashCreate(10);
430  return(ret);
431 }
432 
439 void
440 xmlFreeCatalog(xmlCatalogPtr catal) {
441  if (catal == NULL)
442  return;
443  if (catal->xml != NULL)
444  xmlFreeCatalogEntryList(catal->xml);
445  if (catal->sgml != NULL)
446  xmlHashFree(catal->sgml, xmlFreeCatalogEntry);
447  xmlFree(catal);
448 }
449 
450 /************************************************************************
451  * *
452  * Serializing Catalogs *
453  * *
454  ************************************************************************/
455 
456 #ifdef LIBXML_OUTPUT_ENABLED
457 
464 static void
465 xmlCatalogDumpEntry(void *payload, void *data,
466  const xmlChar *name ATTRIBUTE_UNUSED) {
467  xmlCatalogEntryPtr entry = (xmlCatalogEntryPtr) payload;
468  FILE *out = (FILE *) data;
469  if ((entry == NULL) || (out == NULL))
470  return;
471  switch (entry->type) {
472  case SGML_CATA_ENTITY:
473  fprintf(out, "ENTITY "); break;
474  case SGML_CATA_PENTITY:
475  fprintf(out, "ENTITY %%"); break;
476  case SGML_CATA_DOCTYPE:
477  fprintf(out, "DOCTYPE "); break;
478  case SGML_CATA_LINKTYPE:
479  fprintf(out, "LINKTYPE "); break;
480  case SGML_CATA_NOTATION:
481  fprintf(out, "NOTATION "); break;
482  case SGML_CATA_PUBLIC:
483  fprintf(out, "PUBLIC "); break;
484  case SGML_CATA_SYSTEM:
485  fprintf(out, "SYSTEM "); break;
486  case SGML_CATA_DELEGATE:
487  fprintf(out, "DELEGATE "); break;
488  case SGML_CATA_BASE:
489  fprintf(out, "BASE "); break;
490  case SGML_CATA_CATALOG:
491  fprintf(out, "CATALOG "); break;
492  case SGML_CATA_DOCUMENT:
493  fprintf(out, "DOCUMENT "); break;
494  case SGML_CATA_SGMLDECL:
495  fprintf(out, "SGMLDECL "); break;
496  default:
497  return;
498  }
499  switch (entry->type) {
500  case SGML_CATA_ENTITY:
501  case SGML_CATA_PENTITY:
502  case SGML_CATA_DOCTYPE:
503  case SGML_CATA_LINKTYPE:
504  case SGML_CATA_NOTATION:
505  fprintf(out, "%s", (const char *) entry->name); break;
506  case SGML_CATA_PUBLIC:
507  case SGML_CATA_SYSTEM:
508  case SGML_CATA_SGMLDECL:
509  case SGML_CATA_DOCUMENT:
510  case SGML_CATA_CATALOG:
511  case SGML_CATA_BASE:
512  case SGML_CATA_DELEGATE:
513  fprintf(out, "\"%s\"", entry->name); break;
514  default:
515  break;
516  }
517  switch (entry->type) {
518  case SGML_CATA_ENTITY:
519  case SGML_CATA_PENTITY:
520  case SGML_CATA_DOCTYPE:
521  case SGML_CATA_LINKTYPE:
522  case SGML_CATA_NOTATION:
523  case SGML_CATA_PUBLIC:
524  case SGML_CATA_SYSTEM:
525  case SGML_CATA_DELEGATE:
526  fprintf(out, " \"%s\"", entry->value); break;
527  default:
528  break;
529  }
530  fprintf(out, "\n");
531 }
532 
544 static void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog,
545  xmlDocPtr doc, xmlNsPtr ns, xmlCatalogEntryPtr cgroup) {
547  xmlCatalogEntryPtr cur;
548  /*
549  * add all the catalog entries
550  */
551  cur = catal;
552  while (cur != NULL) {
553  if (cur->group == cgroup) {
554  switch (cur->type) {
555  case XML_CATA_REMOVED:
556  break;
557  case XML_CATA_BROKEN_CATALOG:
558  case XML_CATA_CATALOG:
559  if (cur == catal) {
560  cur = cur->children;
561  continue;
562  }
563  break;
564  case XML_CATA_NEXT_CATALOG:
565  node = xmlNewDocNode(doc, ns, BAD_CAST "nextCatalog", NULL);
566  xmlSetProp(node, BAD_CAST "catalog", cur->value);
567  xmlAddChild(catalog, node);
568  break;
569  case XML_CATA_NONE:
570  break;
571  case XML_CATA_GROUP:
572  node = xmlNewDocNode(doc, ns, BAD_CAST "group", NULL);
573  xmlSetProp(node, BAD_CAST "id", cur->name);
574  if (cur->value != NULL) {
575  xmlNsPtr xns;
577  if (xns != NULL)
578  xmlSetNsProp(node, xns, BAD_CAST "base",
579  cur->value);
580  }
581  switch (cur->prefer) {
582  case XML_CATA_PREFER_NONE:
583  break;
584  case XML_CATA_PREFER_PUBLIC:
585  xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "public");
586  break;
587  case XML_CATA_PREFER_SYSTEM:
588  xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "system");
589  break;
590  }
591  xmlDumpXMLCatalogNode(cur->next, node, doc, ns, cur);
592  xmlAddChild(catalog, node);
593  break;
594  case XML_CATA_PUBLIC:
595  node = xmlNewDocNode(doc, ns, BAD_CAST "public", NULL);
596  xmlSetProp(node, BAD_CAST "publicId", cur->name);
597  xmlSetProp(node, BAD_CAST "uri", cur->value);
598  xmlAddChild(catalog, node);
599  break;
600  case XML_CATA_SYSTEM:
601  node = xmlNewDocNode(doc, ns, BAD_CAST "system", NULL);
602  xmlSetProp(node, BAD_CAST "systemId", cur->name);
603  xmlSetProp(node, BAD_CAST "uri", cur->value);
604  xmlAddChild(catalog, node);
605  break;
606  case XML_CATA_REWRITE_SYSTEM:
607  node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteSystem", NULL);
608  xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
609  xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
610  xmlAddChild(catalog, node);
611  break;
612  case XML_CATA_DELEGATE_PUBLIC:
613  node = xmlNewDocNode(doc, ns, BAD_CAST "delegatePublic", NULL);
614  xmlSetProp(node, BAD_CAST "publicIdStartString", cur->name);
615  xmlSetProp(node, BAD_CAST "catalog", cur->value);
616  xmlAddChild(catalog, node);
617  break;
618  case XML_CATA_DELEGATE_SYSTEM:
619  node = xmlNewDocNode(doc, ns, BAD_CAST "delegateSystem", NULL);
620  xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
621  xmlSetProp(node, BAD_CAST "catalog", cur->value);
622  xmlAddChild(catalog, node);
623  break;
624  case XML_CATA_URI:
625  node = xmlNewDocNode(doc, ns, BAD_CAST "uri", NULL);
626  xmlSetProp(node, BAD_CAST "name", cur->name);
627  xmlSetProp(node, BAD_CAST "uri", cur->value);
628  xmlAddChild(catalog, node);
629  break;
630  case XML_CATA_REWRITE_URI:
631  node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteURI", NULL);
632  xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
633  xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
634  xmlAddChild(catalog, node);
635  break;
636  case XML_CATA_DELEGATE_URI:
637  node = xmlNewDocNode(doc, ns, BAD_CAST "delegateURI", NULL);
638  xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
639  xmlSetProp(node, BAD_CAST "catalog", cur->value);
640  xmlAddChild(catalog, node);
641  break;
642  case SGML_CATA_SYSTEM:
643  case SGML_CATA_PUBLIC:
644  case SGML_CATA_ENTITY:
645  case SGML_CATA_PENTITY:
646  case SGML_CATA_DOCTYPE:
647  case SGML_CATA_LINKTYPE:
648  case SGML_CATA_NOTATION:
649  case SGML_CATA_DELEGATE:
650  case SGML_CATA_BASE:
651  case SGML_CATA_CATALOG:
652  case SGML_CATA_DOCUMENT:
653  case SGML_CATA_SGMLDECL:
654  break;
655  }
656  }
657  cur = cur->next;
658  }
659 }
660 
661 static int
662 xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) {
663  int ret;
664  xmlDocPtr doc;
665  xmlNsPtr ns;
666  xmlDtdPtr dtd;
667  xmlNodePtr catalog;
669 
670  /*
671  * Rebuild a catalog
672  */
673  doc = xmlNewDoc(NULL);
674  if (doc == NULL)
675  return(-1);
676  dtd = xmlNewDtd(doc, BAD_CAST "catalog",
677  BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
678 BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd");
679 
680  xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
681 
682  ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL);
683  if (ns == NULL) {
684  xmlFreeDoc(doc);
685  return(-1);
686  }
687  catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL);
688  if (catalog == NULL) {
689  xmlFreeNs(ns);
690  xmlFreeDoc(doc);
691  return(-1);
692  }
693  catalog->nsDef = ns;
694  xmlAddChild((xmlNodePtr) doc, catalog);
695 
696  xmlDumpXMLCatalogNode(catal, catalog, doc, ns, NULL);
697 
698  /*
699  * reserialize it
700  */
701  buf = xmlOutputBufferCreateFile(out, NULL);
702  if (buf == NULL) {
703  xmlFreeDoc(doc);
704  return(-1);
705  }
706  ret = xmlSaveFormatFileTo(buf, doc, NULL, 1);
707 
708  /*
709  * Free it
710  */
711  xmlFreeDoc(doc);
712 
713  return(ret);
714 }
715 #endif /* LIBXML_OUTPUT_ENABLED */
716 
717 /************************************************************************
718  * *
719  * Converting SGML Catalogs to XML *
720  * *
721  ************************************************************************/
722 
730 static void
731 xmlCatalogConvertEntry(void *payload, void *data,
732  const xmlChar *name ATTRIBUTE_UNUSED) {
733  xmlCatalogEntryPtr entry = (xmlCatalogEntryPtr) payload;
734  xmlCatalogPtr catal = (xmlCatalogPtr) data;
735  if ((entry == NULL) || (catal == NULL) || (catal->sgml == NULL) ||
736  (catal->xml == NULL))
737  return;
738  switch (entry->type) {
739  case SGML_CATA_ENTITY:
740  entry->type = XML_CATA_PUBLIC;
741  break;
742  case SGML_CATA_PENTITY:
743  entry->type = XML_CATA_PUBLIC;
744  break;
745  case SGML_CATA_DOCTYPE:
746  entry->type = XML_CATA_PUBLIC;
747  break;
748  case SGML_CATA_LINKTYPE:
749  entry->type = XML_CATA_PUBLIC;
750  break;
751  case SGML_CATA_NOTATION:
752  entry->type = XML_CATA_PUBLIC;
753  break;
754  case SGML_CATA_PUBLIC:
755  entry->type = XML_CATA_PUBLIC;
756  break;
757  case SGML_CATA_SYSTEM:
758  entry->type = XML_CATA_SYSTEM;
759  break;
760  case SGML_CATA_DELEGATE:
761  entry->type = XML_CATA_DELEGATE_PUBLIC;
762  break;
763  case SGML_CATA_CATALOG:
764  entry->type = XML_CATA_CATALOG;
765  break;
766  default:
767  xmlHashRemoveEntry(catal->sgml, entry->name, xmlFreeCatalogEntry);
768  return;
769  }
770  /*
771  * Conversion successful, remove from the SGML catalog
772  * and add it to the default XML one
773  */
774  xmlHashRemoveEntry(catal->sgml, entry->name, NULL);
775  entry->parent = catal->xml;
776  entry->next = NULL;
777  if (catal->xml->children == NULL)
778  catal->xml->children = entry;
779  else {
780  xmlCatalogEntryPtr prev;
781 
782  prev = catal->xml->children;
783  while (prev->next != NULL)
784  prev = prev->next;
785  prev->next = entry;
786  }
787 }
788 
797 int
798 xmlConvertSGMLCatalog(xmlCatalogPtr catal) {
799 
800  if ((catal == NULL) || (catal->type != XML_SGML_CATALOG_TYPE))
801  return(-1);
802 
803  if (xmlDebugCatalogs) {
805  "Converting SGML catalog to XML\n");
806  }
807  xmlHashScan(catal->sgml, xmlCatalogConvertEntry, &catal);
808  return(0);
809 }
810 
811 /************************************************************************
812  * *
813  * Helper function *
814  * *
815  ************************************************************************/
816 
826 static xmlChar *
827 xmlCatalogUnWrapURN(const xmlChar *urn) {
828  xmlChar result[2000];
829  unsigned int i = 0;
830 
831  if (xmlStrncmp(urn, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1))
832  return(NULL);
833  urn += sizeof(XML_URN_PUBID) - 1;
834 
835  while (*urn != 0) {
836  if (i > sizeof(result) - 4)
837  break;
838  if (*urn == '+') {
839  result[i++] = ' ';
840  urn++;
841  } else if (*urn == ':') {
842  result[i++] = '/';
843  result[i++] = '/';
844  urn++;
845  } else if (*urn == ';') {
846  result[i++] = ':';
847  result[i++] = ':';
848  urn++;
849  } else if (*urn == '%') {
850  if ((urn[1] == '2') && (urn[2] == 'B'))
851  result[i++] = '+';
852  else if ((urn[1] == '3') && (urn[2] == 'A'))
853  result[i++] = ':';
854  else if ((urn[1] == '2') && (urn[2] == 'F'))
855  result[i++] = '/';
856  else if ((urn[1] == '3') && (urn[2] == 'B'))
857  result[i++] = ';';
858  else if ((urn[1] == '2') && (urn[2] == '7'))
859  result[i++] = '\'';
860  else if ((urn[1] == '3') && (urn[2] == 'F'))
861  result[i++] = '?';
862  else if ((urn[1] == '2') && (urn[2] == '3'))
863  result[i++] = '#';
864  else if ((urn[1] == '2') && (urn[2] == '5'))
865  result[i++] = '%';
866  else {
867  result[i++] = *urn;
868  urn++;
869  continue;
870  }
871  urn += 3;
872  } else {
873  result[i++] = *urn;
874  urn++;
875  }
876  }
877  result[i] = 0;
878 
879  return(xmlStrdup(result));
880 }
881 
892 xmlDocPtr
893 xmlParseCatalogFile(const char *filename) {
894  xmlDocPtr ret;
895  xmlParserCtxtPtr ctxt;
896  char *directory = NULL;
897  xmlParserInputPtr inputStream;
899 
900  ctxt = xmlNewParserCtxt();
901  if (ctxt == NULL) {
902 #ifdef LIBXML_SAX1_ENABLED
904  xmlDefaultSAXHandler.error(NULL, "out of memory\n");
905  }
906 #endif
907  return(NULL);
908  }
909 
911  if (buf == NULL) {
912  xmlFreeParserCtxt(ctxt);
913  return(NULL);
914  }
915 
916  inputStream = xmlNewInputStream(ctxt);
917  if (inputStream == NULL) {
918  xmlFreeParserCtxt(ctxt);
919  return(NULL);
920  }
921 
922  inputStream->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
923  inputStream->buf = buf;
924  xmlBufResetInput(buf->buffer, inputStream);
925 
926  inputPush(ctxt, inputStream);
927  if (ctxt->directory == NULL)
929  if ((ctxt->directory == NULL) && (directory != NULL))
930  ctxt->directory = directory;
931  ctxt->valid = 0;
932  ctxt->validate = 0;
933  ctxt->loadsubset = 0;
934  ctxt->pedantic = 0;
935  ctxt->dictNames = 1;
936 
937  xmlParseDocument(ctxt);
938 
939  if (ctxt->wellFormed)
940  ret = ctxt->myDoc;
941  else {
942  ret = NULL;
943  xmlFreeDoc(ctxt->myDoc);
944  ctxt->myDoc = NULL;
945  }
946  xmlFreeParserCtxt(ctxt);
947 
948  return(ret);
949 }
950 
959 static xmlChar *
960 xmlLoadFileContent(const char *filename)
961 {
962 #ifdef HAVE_STAT
963  int fd;
964 #else
965  FILE *fd;
966 #endif
967  int len;
968  long size;
969 
970 #ifdef HAVE_STAT
971  struct stat info;
972 #endif
973  xmlChar *content;
974 
975  if (filename == NULL)
976  return (NULL);
977 
978 #ifdef HAVE_STAT
979  if (stat(filename, &info) < 0)
980  return (NULL);
981 #endif
982 
983 #ifdef HAVE_STAT
984  if ((fd = open(filename, O_RDONLY)) < 0)
985 #else
986  if ((fd = fopen(filename, "rb")) == NULL)
987 #endif
988  {
989  return (NULL);
990  }
991 #ifdef HAVE_STAT
992  size = info.st_size;
993 #else
994  if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */
995  fclose(fd);
996  return (NULL);
997  }
998 #endif
1000  if (content == NULL) {
1001  xmlCatalogErrMemory("allocating catalog data");
1002 #ifdef HAVE_STAT
1003  close(fd);
1004 #else
1005  fclose(fd);
1006 #endif
1007  return (NULL);
1008  }
1009 #ifdef HAVE_STAT
1010  len = read(fd, content, size);
1011  close(fd);
1012 #else
1013  len = fread(content, 1, size, fd);
1014  fclose(fd);
1015 #endif
1016  if (len < 0) {
1017  xmlFree(content);
1018  return (NULL);
1019  }
1020  content[len] = 0;
1021 
1022  return(content);
1023 }
1024 
1037 static xmlChar *
1038 xmlCatalogNormalizePublic(const xmlChar *pubID)
1039 {
1040  int ok = 1;
1041  int white;
1042  const xmlChar *p;
1043  xmlChar *ret;
1044  xmlChar *q;
1045 
1046  if (pubID == NULL)
1047  return(NULL);
1048 
1049  white = 1;
1050  for (p = pubID;*p != 0 && ok;p++) {
1051  if (!xmlIsBlank_ch(*p))
1052  white = 0;
1053  else if (*p == 0x20 && !white)
1054  white = 1;
1055  else
1056  ok = 0;
1057  }
1058  if (ok && !white) /* is normalized */
1059  return(NULL);
1060 
1061  ret = xmlStrdup(pubID);
1062  q = ret;
1063  white = 0;
1064  for (p = pubID;*p != 0;p++) {
1065  if (xmlIsBlank_ch(*p)) {
1066  if (q != ret)
1067  white = 1;
1068  } else {
1069  if (white) {
1070  *(q++) = 0x20;
1071  white = 0;
1072  }
1073  *(q++) = *p;
1074  }
1075  }
1076  *q = 0;
1077  return(ret);
1078 }
1079 
1080 /************************************************************************
1081  * *
1082  * The XML Catalog parser *
1083  * *
1084  ************************************************************************/
1085 
1086 static xmlCatalogEntryPtr
1087 xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename);
1088 static void
1089 xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
1090  xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup);
1091 static xmlChar *
1092 xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
1093  const xmlChar *sysID);
1094 static xmlChar *
1095 xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI);
1096 
1097 
1106 static xmlCatalogEntryType
1107 xmlGetXMLCatalogEntryType(const xmlChar *name) {
1108  xmlCatalogEntryType type = XML_CATA_NONE;
1109  if (xmlStrEqual(name, (const xmlChar *) "system"))
1110  type = XML_CATA_SYSTEM;
1111  else if (xmlStrEqual(name, (const xmlChar *) "public"))
1112  type = XML_CATA_PUBLIC;
1113  else if (xmlStrEqual(name, (const xmlChar *) "rewriteSystem"))
1114  type = XML_CATA_REWRITE_SYSTEM;
1115  else if (xmlStrEqual(name, (const xmlChar *) "delegatePublic"))
1116  type = XML_CATA_DELEGATE_PUBLIC;
1117  else if (xmlStrEqual(name, (const xmlChar *) "delegateSystem"))
1118  type = XML_CATA_DELEGATE_SYSTEM;
1119  else if (xmlStrEqual(name, (const xmlChar *) "uri"))
1120  type = XML_CATA_URI;
1121  else if (xmlStrEqual(name, (const xmlChar *) "rewriteURI"))
1122  type = XML_CATA_REWRITE_URI;
1123  else if (xmlStrEqual(name, (const xmlChar *) "delegateURI"))
1124  type = XML_CATA_DELEGATE_URI;
1125  else if (xmlStrEqual(name, (const xmlChar *) "nextCatalog"))
1126  type = XML_CATA_NEXT_CATALOG;
1127  else if (xmlStrEqual(name, (const xmlChar *) "catalog"))
1128  type = XML_CATA_CATALOG;
1129  return(type);
1130 }
1131 
1147 static xmlCatalogEntryPtr
1148 xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
1149  const xmlChar *name, const xmlChar *attrName,
1150  const xmlChar *uriAttrName, xmlCatalogPrefer prefer,
1151  xmlCatalogEntryPtr cgroup) {
1152  int ok = 1;
1153  xmlChar *uriValue;
1154  xmlChar *nameValue = NULL;
1155  xmlChar *base = NULL;
1156  xmlChar *URL = NULL;
1157  xmlCatalogEntryPtr ret = NULL;
1158 
1159  if (attrName != NULL) {
1160  nameValue = xmlGetProp(cur, attrName);
1161  if (nameValue == NULL) {
1162  xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
1163  "%s entry lacks '%s'\n", name, attrName, NULL);
1164  ok = 0;
1165  }
1166  }
1167  uriValue = xmlGetProp(cur, uriAttrName);
1168  if (uriValue == NULL) {
1169  xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
1170  "%s entry lacks '%s'\n", name, uriAttrName, NULL);
1171  ok = 0;
1172  }
1173  if (!ok) {
1174  if (nameValue != NULL)
1175  xmlFree(nameValue);
1176  if (uriValue != NULL)
1177  xmlFree(uriValue);
1178  return(NULL);
1179  }
1180 
1181  base = xmlNodeGetBase(cur->doc, cur);
1182  URL = xmlBuildURI(uriValue, base);
1183  if (URL != NULL) {
1184  if (xmlDebugCatalogs > 1) {
1185  if (nameValue != NULL)
1187  "Found %s: '%s' '%s'\n", name, nameValue, URL);
1188  else
1190  "Found %s: '%s'\n", name, URL);
1191  }
1192  ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer, cgroup);
1193  } else {
1194  xmlCatalogErr(ret, cur, XML_CATALOG_ENTRY_BROKEN,
1195  "%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);
1196  }
1197  if (nameValue != NULL)
1198  xmlFree(nameValue);
1199  if (uriValue != NULL)
1200  xmlFree(uriValue);
1201  if (base != NULL)
1202  xmlFree(base);
1203  if (URL != NULL)
1204  xmlFree(URL);
1205  return(ret);
1206 }
1207 
1219 static void
1220 xmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer,
1221  xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup)
1222 {
1223  xmlChar *base = NULL;
1224  xmlCatalogEntryPtr entry = NULL;
1225 
1226  if (cur == NULL)
1227  return;
1228  if (xmlStrEqual(cur->name, BAD_CAST "group")) {
1229  xmlChar *prop;
1230  xmlCatalogPrefer pref = XML_CATA_PREFER_NONE;
1231 
1232  prop = xmlGetProp(cur, BAD_CAST "prefer");
1233  if (prop != NULL) {
1234  if (xmlStrEqual(prop, BAD_CAST "system")) {
1235  prefer = XML_CATA_PREFER_SYSTEM;
1236  } else if (xmlStrEqual(prop, BAD_CAST "public")) {
1237  prefer = XML_CATA_PREFER_PUBLIC;
1238  } else {
1239  xmlCatalogErr(parent, cur, XML_CATALOG_PREFER_VALUE,
1240  "Invalid value for prefer: '%s'\n",
1241  prop, NULL, NULL);
1242  }
1243  xmlFree(prop);
1244  pref = prefer;
1245  }
1246  prop = xmlGetProp(cur, BAD_CAST "id");
1248  entry = xmlNewCatalogEntry(XML_CATA_GROUP, prop, base, NULL, pref, cgroup);
1249  xmlFree(prop);
1250  } else if (xmlStrEqual(cur->name, BAD_CAST "public")) {
1251  entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,
1252  BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer, cgroup);
1253  } else if (xmlStrEqual(cur->name, BAD_CAST "system")) {
1254  entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,
1255  BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer, cgroup);
1256  } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {
1257  entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,
1258  BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",
1259  BAD_CAST "rewritePrefix", prefer, cgroup);
1260  } else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {
1261  entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,
1262  BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",
1263  BAD_CAST "catalog", prefer, cgroup);
1264  } else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {
1265  entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,
1266  BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",
1267  BAD_CAST "catalog", prefer, cgroup);
1268  } else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {
1269  entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,
1270  BAD_CAST "uri", BAD_CAST "name",
1271  BAD_CAST "uri", prefer, cgroup);
1272  } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {
1273  entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,
1274  BAD_CAST "rewriteURI", BAD_CAST "uriStartString",
1275  BAD_CAST "rewritePrefix", prefer, cgroup);
1276  } else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {
1277  entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,
1278  BAD_CAST "delegateURI", BAD_CAST "uriStartString",
1279  BAD_CAST "catalog", prefer, cgroup);
1280  } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {
1281  entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,
1282  BAD_CAST "nextCatalog", NULL,
1283  BAD_CAST "catalog", prefer, cgroup);
1284  }
1285  if (entry != NULL) {
1286  if (parent != NULL) {
1287  entry->parent = parent;
1288  if (parent->children == NULL)
1289  parent->children = entry;
1290  else {
1291  xmlCatalogEntryPtr prev;
1292 
1293  prev = parent->children;
1294  while (prev->next != NULL)
1295  prev = prev->next;
1296  prev->next = entry;
1297  }
1298  }
1299  if (entry->type == XML_CATA_GROUP) {
1300  /*
1301  * Recurse to propagate prefer to the subtree
1302  * (xml:base handling is automated)
1303  */
1304  xmlParseXMLCatalogNodeList(cur->children, prefer, parent, entry);
1305  }
1306  }
1307  if (base != NULL)
1308  xmlFree(base);
1309 }
1310 
1322 static void
1323 xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
1324  xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup) {
1325  while (cur != NULL) {
1326  if ((cur->ns != NULL) && (cur->ns->href != NULL) &&
1327  (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
1328  xmlParseXMLCatalogNode(cur, prefer, parent, cgroup);
1329  }
1330  cur = cur->next;
1331  }
1332  /* TODO: sort the list according to REWRITE lengths and prefer value */
1333 }
1334 
1345 static xmlCatalogEntryPtr
1346 xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {
1347  xmlDocPtr doc;
1348  xmlNodePtr cur;
1349  xmlChar *prop;
1350  xmlCatalogEntryPtr parent = NULL;
1351 
1352  if (filename == NULL)
1353  return(NULL);
1354 
1355  doc = xmlParseCatalogFile((const char *) filename);
1356  if (doc == NULL) {
1357  if (xmlDebugCatalogs)
1359  "Failed to parse catalog %s\n", filename);
1360  return(NULL);
1361  }
1362 
1363  if (xmlDebugCatalogs)
1365  "%d Parsing catalog %s\n", xmlGetThreadId(), filename);
1366 
1367  cur = xmlDocGetRootElement(doc);
1368  if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&
1369  (cur->ns != NULL) && (cur->ns->href != NULL) &&
1370  (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
1371 
1372  parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
1373  (const xmlChar *)filename, NULL, prefer, NULL);
1374  if (parent == NULL) {
1375  xmlFreeDoc(doc);
1376  return(NULL);
1377  }
1378 
1379  prop = xmlGetProp(cur, BAD_CAST "prefer");
1380  if (prop != NULL) {
1381  if (xmlStrEqual(prop, BAD_CAST "system")) {
1382  prefer = XML_CATA_PREFER_SYSTEM;
1383  } else if (xmlStrEqual(prop, BAD_CAST "public")) {
1384  prefer = XML_CATA_PREFER_PUBLIC;
1385  } else {
1386  xmlCatalogErr(NULL, cur, XML_CATALOG_PREFER_VALUE,
1387  "Invalid value for prefer: '%s'\n",
1388  prop, NULL, NULL);
1389  }
1390  xmlFree(prop);
1391  }
1392  cur = cur->children;
1393  xmlParseXMLCatalogNodeList(cur, prefer, parent, NULL);
1394  } else {
1395  xmlCatalogErr(NULL, (xmlNodePtr) doc, XML_CATALOG_NOT_CATALOG,
1396  "File %s is not an XML Catalog\n",
1397  filename, NULL, NULL);
1398  xmlFreeDoc(doc);
1399  return(NULL);
1400  }
1401  xmlFreeDoc(doc);
1402  return(parent);
1403 }
1404 
1413 static int
1414 xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
1415  xmlCatalogEntryPtr doc;
1416 
1417  if (catal == NULL)
1418  return(-1);
1419  if (catal->URL == NULL)
1420  return(-1);
1421 
1422  /*
1423  * lock the whole catalog for modification
1424  */
1425  xmlRMutexLock(xmlCatalogMutex);
1426  if (catal->children != NULL) {
1427  /* Okay someone else did it in the meantime */
1428  xmlRMutexUnlock(xmlCatalogMutex);
1429  return(0);
1430  }
1431 
1432  if (xmlCatalogXMLFiles != NULL) {
1433  doc = (xmlCatalogEntryPtr)
1434  xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
1435  if (doc != NULL) {
1436  if (xmlDebugCatalogs)
1438  "Found %s in file hash\n", catal->URL);
1439 
1440  if (catal->type == XML_CATA_CATALOG)
1441  catal->children = doc->children;
1442  else
1443  catal->children = doc;
1444  catal->dealloc = 0;
1445  xmlRMutexUnlock(xmlCatalogMutex);
1446  return(0);
1447  }
1448  if (xmlDebugCatalogs)
1450  "%s not found in file hash\n", catal->URL);
1451  }
1452 
1453  /*
1454  * Fetch and parse. Note that xmlParseXMLCatalogFile does not
1455  * use the existing catalog, there is no recursion allowed at
1456  * that level.
1457  */
1458  doc = xmlParseXMLCatalogFile(catal->prefer, catal->URL);
1459  if (doc == NULL) {
1460  catal->type = XML_CATA_BROKEN_CATALOG;
1461  xmlRMutexUnlock(xmlCatalogMutex);
1462  return(-1);
1463  }
1464 
1465  if (catal->type == XML_CATA_CATALOG)
1466  catal->children = doc->children;
1467  else
1468  catal->children = doc;
1469 
1470  doc->dealloc = 1;
1471 
1472  if (xmlCatalogXMLFiles == NULL)
1473  xmlCatalogXMLFiles = xmlHashCreate(10);
1474  if (xmlCatalogXMLFiles != NULL) {
1475  if (xmlDebugCatalogs)
1477  "%s added to file hash\n", catal->URL);
1478  xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc);
1479  }
1480  xmlRMutexUnlock(xmlCatalogMutex);
1481  return(0);
1482 }
1483 
1484 /************************************************************************
1485  * *
1486  * XML Catalog handling *
1487  * *
1488  ************************************************************************/
1489 
1502 static int
1503 xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
1504  const xmlChar *orig, const xmlChar *replace) {
1505  xmlCatalogEntryPtr cur;
1506  xmlCatalogEntryType typ;
1507  int doregister = 0;
1508 
1509  if ((catal == NULL) ||
1510  ((catal->type != XML_CATA_CATALOG) &&
1511  (catal->type != XML_CATA_BROKEN_CATALOG)))
1512  return(-1);
1513  if (catal->children == NULL) {
1514  xmlFetchXMLCatalogFile(catal);
1515  }
1516  if (catal->children == NULL)
1517  doregister = 1;
1518 
1519  typ = xmlGetXMLCatalogEntryType(type);
1520  if (typ == XML_CATA_NONE) {
1521  if (xmlDebugCatalogs)
1523  "Failed to add unknown element %s to catalog\n", type);
1524  return(-1);
1525  }
1526 
1527  cur = catal->children;
1528  /*
1529  * Might be a simple "update in place"
1530  */
1531  if (cur != NULL) {
1532  while (cur != NULL) {
1533  if ((orig != NULL) && (cur->type == typ) &&
1534  (xmlStrEqual(orig, cur->name))) {
1535  if (xmlDebugCatalogs)
1537  "Updating element %s to catalog\n", type);
1538  if (cur->value != NULL)
1539  xmlFree(cur->value);
1540  if (cur->URL != NULL)
1541  xmlFree(cur->URL);
1542  cur->value = xmlStrdup(replace);
1543  cur->URL = xmlStrdup(replace);
1544  return(0);
1545  }
1546  if (cur->next == NULL)
1547  break;
1548  cur = cur->next;
1549  }
1550  }
1551  if (xmlDebugCatalogs)
1553  "Adding element %s to catalog\n", type);
1554  if (cur == NULL)
1555  catal->children = xmlNewCatalogEntry(typ, orig, replace,
1556  NULL, catal->prefer, NULL);
1557  else
1558  cur->next = xmlNewCatalogEntry(typ, orig, replace,
1559  NULL, catal->prefer, NULL);
1560  if (doregister) {
1561  catal->type = XML_CATA_CATALOG;
1562  cur = (xmlCatalogEntryPtr)xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
1563  if (cur != NULL)
1564  cur->children = catal->children;
1565  }
1566 
1567  return(0);
1568 }
1569 
1580 static int
1581 xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
1582  xmlCatalogEntryPtr cur;
1583  int ret = 0;
1584 
1585  if ((catal == NULL) ||
1586  ((catal->type != XML_CATA_CATALOG) &&
1587  (catal->type != XML_CATA_BROKEN_CATALOG)))
1588  return(-1);
1589  if (value == NULL)
1590  return(-1);
1591  if (catal->children == NULL) {
1592  xmlFetchXMLCatalogFile(catal);
1593  }
1594 
1595  /*
1596  * Scan the children
1597  */
1598  cur = catal->children;
1599  while (cur != NULL) {
1600  if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) ||
1601  (xmlStrEqual(value, cur->value))) {
1602  if (xmlDebugCatalogs) {
1603  if (cur->name != NULL)
1605  "Removing element %s from catalog\n", cur->name);
1606  else
1608  "Removing element %s from catalog\n", cur->value);
1609  }
1610  cur->type = XML_CATA_REMOVED;
1611  }
1612  cur = cur->next;
1613  }
1614  return(ret);
1615 }
1616 
1631 static xmlChar *
1632 xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
1633  const xmlChar *sysID) {
1634  xmlChar *ret = NULL;
1635  xmlCatalogEntryPtr cur;
1636  int haveDelegate = 0;
1637  int haveNext = 0;
1638 
1639  /*
1640  * protection against loops
1641  */
1642  if (catal->depth > MAX_CATAL_DEPTH) {
1643  xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
1644  "Detected recursion in catalog %s\n",
1645  catal->name, NULL, NULL);
1646  return(NULL);
1647  }
1648  catal->depth++;
1649 
1650  /*
1651  * First tries steps 2/ 3/ 4/ if a system ID is provided.
1652  */
1653  if (sysID != NULL) {
1654  xmlCatalogEntryPtr rewrite = NULL;
1655  int lenrewrite = 0, len;
1656  cur = catal;
1657  haveDelegate = 0;
1658  while (cur != NULL) {
1659  switch (cur->type) {
1660  case XML_CATA_SYSTEM:
1661  if (xmlStrEqual(sysID, cur->name)) {
1662  if (xmlDebugCatalogs)
1664  "Found system match %s, using %s\n",
1665  cur->name, cur->URL);
1666  catal->depth--;
1667  return(xmlStrdup(cur->URL));
1668  }
1669  break;
1670  case XML_CATA_REWRITE_SYSTEM:
1671  len = xmlStrlen(cur->name);
1672  if ((len > lenrewrite) &&
1673  (!xmlStrncmp(sysID, cur->name, len))) {
1674  lenrewrite = len;
1675  rewrite = cur;
1676  }
1677  break;
1678  case XML_CATA_DELEGATE_SYSTEM:
1679  if (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))
1680  haveDelegate++;
1681  break;
1682  case XML_CATA_NEXT_CATALOG:
1683  haveNext++;
1684  break;
1685  default:
1686  break;
1687  }
1688  cur = cur->next;
1689  }
1690  if (rewrite != NULL) {
1691  if (xmlDebugCatalogs)
1693  "Using rewriting rule %s\n", rewrite->name);
1694  ret = xmlStrdup(rewrite->URL);
1695  if (ret != NULL)
1696  ret = xmlStrcat(ret, &sysID[lenrewrite]);
1697  catal->depth--;
1698  return(ret);
1699  }
1700  if (haveDelegate) {
1701  const xmlChar *delegates[MAX_DELEGATE];
1702  int nbList = 0, i;
1703 
1704  /*
1705  * Assume the entries have been sorted by decreasing substring
1706  * matches when the list was produced.
1707  */
1708  cur = catal;
1709  while (cur != NULL) {
1710  if ((cur->type == XML_CATA_DELEGATE_SYSTEM) &&
1711  (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))) {
1712  for (i = 0;i < nbList;i++)
1713  if (xmlStrEqual(cur->URL, delegates[i]))
1714  break;
1715  if (i < nbList) {
1716  cur = cur->next;
1717  continue;
1718  }
1719  if (nbList < MAX_DELEGATE)
1720  delegates[nbList++] = cur->URL;
1721 
1722  if (cur->children == NULL) {
1723  xmlFetchXMLCatalogFile(cur);
1724  }
1725  if (cur->children != NULL) {
1726  if (xmlDebugCatalogs)
1728  "Trying system delegate %s\n", cur->URL);
1729  ret = xmlCatalogListXMLResolve(
1730  cur->children, NULL, sysID);
1731  if (ret != NULL) {
1732  catal->depth--;
1733  return(ret);
1734  }
1735  }
1736  }
1737  cur = cur->next;
1738  }
1739  /*
1740  * Apply the cut algorithm explained in 4/
1741  */
1742  catal->depth--;
1743  return(XML_CATAL_BREAK);
1744  }
1745  }
1746  /*
1747  * Then tries 5/ 6/ if a public ID is provided
1748  */
1749  if (pubID != NULL) {
1750  cur = catal;
1751  haveDelegate = 0;
1752  while (cur != NULL) {
1753  switch (cur->type) {
1754  case XML_CATA_PUBLIC:
1755  if (xmlStrEqual(pubID, cur->name)) {
1756  if (xmlDebugCatalogs)
1758  "Found public match %s\n", cur->name);
1759  catal->depth--;
1760  return(xmlStrdup(cur->URL));
1761  }
1762  break;
1763  case XML_CATA_DELEGATE_PUBLIC:
1764  if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) &&
1765  (cur->prefer == XML_CATA_PREFER_PUBLIC))
1766  haveDelegate++;
1767  break;
1768  case XML_CATA_NEXT_CATALOG:
1769  if (sysID == NULL)
1770  haveNext++;
1771  break;
1772  default:
1773  break;
1774  }
1775  cur = cur->next;
1776  }
1777  if (haveDelegate) {
1778  const xmlChar *delegates[MAX_DELEGATE];
1779  int nbList = 0, i;
1780 
1781  /*
1782  * Assume the entries have been sorted by decreasing substring
1783  * matches when the list was produced.
1784  */
1785  cur = catal;
1786  while (cur != NULL) {
1787  if ((cur->type == XML_CATA_DELEGATE_PUBLIC) &&
1788  (cur->prefer == XML_CATA_PREFER_PUBLIC) &&
1789  (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))) {
1790 
1791  for (i = 0;i < nbList;i++)
1792  if (xmlStrEqual(cur->URL, delegates[i]))
1793  break;
1794  if (i < nbList) {
1795  cur = cur->next;
1796  continue;
1797  }
1798  if (nbList < MAX_DELEGATE)
1799  delegates[nbList++] = cur->URL;
1800 
1801  if (cur->children == NULL) {
1802  xmlFetchXMLCatalogFile(cur);
1803  }
1804  if (cur->children != NULL) {
1805  if (xmlDebugCatalogs)
1807  "Trying public delegate %s\n", cur->URL);
1808  ret = xmlCatalogListXMLResolve(
1809  cur->children, pubID, NULL);
1810  if (ret != NULL) {
1811  catal->depth--;
1812  return(ret);
1813  }
1814  }
1815  }
1816  cur = cur->next;
1817  }
1818  /*
1819  * Apply the cut algorithm explained in 4/
1820  */
1821  catal->depth--;
1822  return(XML_CATAL_BREAK);
1823  }
1824  }
1825  if (haveNext) {
1826  cur = catal;
1827  while (cur != NULL) {
1828  if (cur->type == XML_CATA_NEXT_CATALOG) {
1829  if (cur->children == NULL) {
1830  xmlFetchXMLCatalogFile(cur);
1831  }
1832  if (cur->children != NULL) {
1833  ret = xmlCatalogListXMLResolve(cur->children, pubID, sysID);
1834  if (ret != NULL) {
1835  catal->depth--;
1836  return(ret);
1837  } else if (catal->depth > MAX_CATAL_DEPTH) {
1838  return(NULL);
1839  }
1840  }
1841  }
1842  cur = cur->next;
1843  }
1844  }
1845 
1846  catal->depth--;
1847  return(NULL);
1848 }
1849 
1864 static xmlChar *
1865 xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
1866  xmlChar *ret = NULL;
1867  xmlCatalogEntryPtr cur;
1868  int haveDelegate = 0;
1869  int haveNext = 0;
1870  xmlCatalogEntryPtr rewrite = NULL;
1871  int lenrewrite = 0, len;
1872 
1873  if (catal == NULL)
1874  return(NULL);
1875 
1876  if (URI == NULL)
1877  return(NULL);
1878 
1879  if (catal->depth > MAX_CATAL_DEPTH) {
1880  xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
1881  "Detected recursion in catalog %s\n",
1882  catal->name, NULL, NULL);
1883  return(NULL);
1884  }
1885 
1886  /*
1887  * First tries steps 2/ 3/ 4/ if a system ID is provided.
1888  */
1889  cur = catal;
1890  haveDelegate = 0;
1891  while (cur != NULL) {
1892  switch (cur->type) {
1893  case XML_CATA_URI:
1894  if (xmlStrEqual(URI, cur->name)) {
1895  if (xmlDebugCatalogs)
1897  "Found URI match %s\n", cur->name);
1898  return(xmlStrdup(cur->URL));
1899  }
1900  break;
1901  case XML_CATA_REWRITE_URI:
1902  len = xmlStrlen(cur->name);
1903  if ((len > lenrewrite) &&
1904  (!xmlStrncmp(URI, cur->name, len))) {
1905  lenrewrite = len;
1906  rewrite = cur;
1907  }
1908  break;
1909  case XML_CATA_DELEGATE_URI:
1910  if (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))
1911  haveDelegate++;
1912  break;
1913  case XML_CATA_NEXT_CATALOG:
1914  haveNext++;
1915  break;
1916  default:
1917  break;
1918  }
1919  cur = cur->next;
1920  }
1921  if (rewrite != NULL) {
1922  if (xmlDebugCatalogs)
1924  "Using rewriting rule %s\n", rewrite->name);
1925  ret = xmlStrdup(rewrite->URL);
1926  if (ret != NULL)
1927  ret = xmlStrcat(ret, &URI[lenrewrite]);
1928  return(ret);
1929  }
1930  if (haveDelegate) {
1931  const xmlChar *delegates[MAX_DELEGATE];
1932  int nbList = 0, i;
1933 
1934  /*
1935  * Assume the entries have been sorted by decreasing substring
1936  * matches when the list was produced.
1937  */
1938  cur = catal;
1939  while (cur != NULL) {
1940  if (((cur->type == XML_CATA_DELEGATE_SYSTEM) ||
1941  (cur->type == XML_CATA_DELEGATE_URI)) &&
1942  (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))) {
1943  for (i = 0;i < nbList;i++)
1944  if (xmlStrEqual(cur->URL, delegates[i]))
1945  break;
1946  if (i < nbList) {
1947  cur = cur->next;
1948  continue;
1949  }
1950  if (nbList < MAX_DELEGATE)
1951  delegates[nbList++] = cur->URL;
1952 
1953  if (cur->children == NULL) {
1954  xmlFetchXMLCatalogFile(cur);
1955  }
1956  if (cur->children != NULL) {
1957  if (xmlDebugCatalogs)
1959  "Trying URI delegate %s\n", cur->URL);
1960  ret = xmlCatalogListXMLResolveURI(
1961  cur->children, URI);
1962  if (ret != NULL)
1963  return(ret);
1964  }
1965  }
1966  cur = cur->next;
1967  }
1968  /*
1969  * Apply the cut algorithm explained in 4/
1970  */
1971  return(XML_CATAL_BREAK);
1972  }
1973  if (haveNext) {
1974  cur = catal;
1975  while (cur != NULL) {
1976  if (cur->type == XML_CATA_NEXT_CATALOG) {
1977  if (cur->children == NULL) {
1978  xmlFetchXMLCatalogFile(cur);
1979  }
1980  if (cur->children != NULL) {
1981  ret = xmlCatalogListXMLResolveURI(cur->children, URI);
1982  if (ret != NULL)
1983  return(ret);
1984  }
1985  }
1986  cur = cur->next;
1987  }
1988  }
1989 
1990  return(NULL);
1991 }
1992 
2007 static xmlChar *
2008 xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
2009  const xmlChar *sysID) {
2010  xmlChar *ret = NULL;
2011  xmlChar *urnID = NULL;
2012  xmlChar *normid;
2013 
2014  if (catal == NULL)
2015  return(NULL);
2016  if ((pubID == NULL) && (sysID == NULL))
2017  return(NULL);
2018 
2019  normid = xmlCatalogNormalizePublic(pubID);
2020  if (normid != NULL)
2021  pubID = (*normid != 0 ? normid : NULL);
2022 
2023  if (!xmlStrncmp(pubID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
2024  urnID = xmlCatalogUnWrapURN(pubID);
2025  if (xmlDebugCatalogs) {
2026  if (urnID == NULL)
2028  "Public URN ID %s expanded to NULL\n", pubID);
2029  else
2031  "Public URN ID expanded to %s\n", urnID);
2032  }
2033  ret = xmlCatalogListXMLResolve(catal, urnID, sysID);
2034  if (urnID != NULL)
2035  xmlFree(urnID);
2036  if (normid != NULL)
2037  xmlFree(normid);
2038  return(ret);
2039  }
2040  if (!xmlStrncmp(sysID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
2041  urnID = xmlCatalogUnWrapURN(sysID);
2042  if (xmlDebugCatalogs) {
2043  if (urnID == NULL)
2045  "System URN ID %s expanded to NULL\n", sysID);
2046  else
2048  "System URN ID expanded to %s\n", urnID);
2049  }
2050  if (pubID == NULL)
2051  ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
2052  else if (xmlStrEqual(pubID, urnID))
2053  ret = xmlCatalogListXMLResolve(catal, pubID, NULL);
2054  else {
2055  ret = xmlCatalogListXMLResolve(catal, pubID, urnID);
2056  }
2057  if (urnID != NULL)
2058  xmlFree(urnID);
2059  if (normid != NULL)
2060  xmlFree(normid);
2061  return(ret);
2062  }
2063  while (catal != NULL) {
2064  if (catal->type == XML_CATA_CATALOG) {
2065  if (catal->children == NULL) {
2066  xmlFetchXMLCatalogFile(catal);
2067  }
2068  if (catal->children != NULL) {
2069  ret = xmlCatalogXMLResolve(catal->children, pubID, sysID);
2070  if (ret != NULL) {
2071  break;
2072  } else if (catal->children->depth > MAX_CATAL_DEPTH) {
2073  ret = NULL;
2074  break;
2075  }
2076  }
2077  }
2078  catal = catal->next;
2079  }
2080  if (normid != NULL)
2081  xmlFree(normid);
2082  return(ret);
2083 }
2084 
2097 static xmlChar *
2098 xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
2099  xmlChar *ret = NULL;
2100  xmlChar *urnID = NULL;
2101 
2102  if (catal == NULL)
2103  return(NULL);
2104  if (URI == NULL)
2105  return(NULL);
2106 
2107  if (!xmlStrncmp(URI, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
2108  urnID = xmlCatalogUnWrapURN(URI);
2109  if (xmlDebugCatalogs) {
2110  if (urnID == NULL)
2112  "URN ID %s expanded to NULL\n", URI);
2113  else
2115  "URN ID expanded to %s\n", urnID);
2116  }
2117  ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
2118  if (urnID != NULL)
2119  xmlFree(urnID);
2120  return(ret);
2121  }
2122  while (catal != NULL) {
2123  if (catal->type == XML_CATA_CATALOG) {
2124  if (catal->children == NULL) {
2125  xmlFetchXMLCatalogFile(catal);
2126  }
2127  if (catal->children != NULL) {
2128  ret = xmlCatalogXMLResolveURI(catal->children, URI);
2129  if (ret != NULL)
2130  return(ret);
2131  }
2132  }
2133  catal = catal->next;
2134  }
2135  return(ret);
2136 }
2137 
2138 /************************************************************************
2139  * *
2140  * The SGML Catalog parser *
2141  * *
2142  ************************************************************************/
2143 
2144 
2145 #define RAW *cur
2146 #define NEXT cur++;
2147 #define SKIP(x) cur += x;
2148 
2149 #define SKIP_BLANKS while (IS_BLANK_CH(*cur)) NEXT;
2150 
2159 static const xmlChar *
2160 xmlParseSGMLCatalogComment(const xmlChar *cur) {
2161  if ((cur[0] != '-') || (cur[1] != '-'))
2162  return(cur);
2163  SKIP(2);
2164  while ((cur[0] != 0) && ((cur[0] != '-') || ((cur[1] != '-'))))
2165  NEXT;
2166  if (cur[0] == 0) {
2167  return(NULL);
2168  }
2169  return(cur + 2);
2170 }
2171 
2181 static const xmlChar *
2182 xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) {
2183  xmlChar *buf = NULL, *tmp;
2184  int len = 0;
2185  int size = 50;
2186  xmlChar stop;
2187  int count = 0;
2188 
2189  *id = NULL;
2190 
2191  if (RAW == '"') {
2192  NEXT;
2193  stop = '"';
2194  } else if (RAW == '\'') {
2195  NEXT;
2196  stop = '\'';
2197  } else {
2198  stop = ' ';
2199  }
2200  buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
2201  if (buf == NULL) {
2202  xmlCatalogErrMemory("allocating public ID");
2203  return(NULL);
2204  }
2205  while (IS_PUBIDCHAR_CH(*cur) || (*cur == '?')) {
2206  if ((*cur == stop) && (stop != ' '))
2207  break;
2208  if ((stop == ' ') && (IS_BLANK_CH(*cur)))
2209  break;
2210  if (len + 1 >= size) {
2211  size *= 2;
2212  tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
2213  if (tmp == NULL) {
2214  xmlCatalogErrMemory("allocating public ID");
2215  xmlFree(buf);
2216  return(NULL);
2217  }
2218  buf = tmp;
2219  }
2220  buf[len++] = *cur;
2221  count++;
2222  NEXT;
2223  }
2224  buf[len] = 0;
2225  if (stop == ' ') {
2226  if (!IS_BLANK_CH(*cur)) {
2227  xmlFree(buf);
2228  return(NULL);
2229  }
2230  } else {
2231  if (*cur != stop) {
2232  xmlFree(buf);
2233  return(NULL);
2234  }
2235  NEXT;
2236  }
2237  *id = buf;
2238  return(cur);
2239 }
2240 
2250 static const xmlChar *
2251 xmlParseSGMLCatalogName(const xmlChar *cur, xmlChar **name) {
2253  int len = 0;
2254  int c;
2255 
2256  *name = NULL;
2257 
2258  /*
2259  * Handler for more complex cases
2260  */
2261  c = *cur;
2262  if ((!IS_LETTER(c) && (c != '_') && (c != ':'))) {
2263  return(NULL);
2264  }
2265 
2266  while (((IS_LETTER(c)) || (IS_DIGIT(c)) ||
2267  (c == '.') || (c == '-') ||
2268  (c == '_') || (c == ':'))) {
2269  buf[len++] = c;
2270  cur++;
2271  c = *cur;
2272  if (len >= XML_MAX_NAMELEN)
2273  return(NULL);
2274  }
2275  *name = xmlStrndup(buf, len);
2276  return(cur);
2277 }
2278 
2287 static xmlCatalogEntryType
2288 xmlGetSGMLCatalogEntryType(const xmlChar *name) {
2289  xmlCatalogEntryType type = XML_CATA_NONE;
2290  if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
2291  type = SGML_CATA_SYSTEM;
2292  else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
2293  type = SGML_CATA_PUBLIC;
2294  else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
2295  type = SGML_CATA_DELEGATE;
2296  else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
2297  type = SGML_CATA_ENTITY;
2298  else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
2299  type = SGML_CATA_DOCTYPE;
2300  else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
2301  type = SGML_CATA_LINKTYPE;
2302  else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
2303  type = SGML_CATA_NOTATION;
2304  else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
2305  type = SGML_CATA_SGMLDECL;
2306  else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
2307  type = SGML_CATA_DOCUMENT;
2308  else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
2309  type = SGML_CATA_CATALOG;
2310  else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
2311  type = SGML_CATA_BASE;
2312  return(type);
2313 }
2314 
2328 static int
2329 xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value,
2330  const char *file, int super) {
2331  const xmlChar *cur = value;
2332  xmlChar *base = NULL;
2333  int res;
2334 
2335  if ((cur == NULL) || (file == NULL))
2336  return(-1);
2337  base = xmlStrdup((const xmlChar *) file);
2338 
2339  while ((cur != NULL) && (cur[0] != 0)) {
2340  SKIP_BLANKS;
2341  if (cur[0] == 0)
2342  break;
2343  if ((cur[0] == '-') && (cur[1] == '-')) {
2344  cur = xmlParseSGMLCatalogComment(cur);
2345  if (cur == NULL) {
2346  /* error */
2347  break;
2348  }
2349  } else {
2350  xmlChar *sysid = NULL;
2351  xmlChar *name = NULL;
2352  xmlCatalogEntryType type = XML_CATA_NONE;
2353 
2354  cur = xmlParseSGMLCatalogName(cur, &name);
2355  if (cur == NULL || name == NULL) {
2356  /* error */
2357  break;
2358  }
2359  if (!IS_BLANK_CH(*cur)) {
2360  /* error */
2361  break;
2362  }
2363  SKIP_BLANKS;
2364  if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
2365  type = SGML_CATA_SYSTEM;
2366  else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
2367  type = SGML_CATA_PUBLIC;
2368  else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
2369  type = SGML_CATA_DELEGATE;
2370  else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
2371  type = SGML_CATA_ENTITY;
2372  else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
2373  type = SGML_CATA_DOCTYPE;
2374  else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
2375  type = SGML_CATA_LINKTYPE;
2376  else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
2377  type = SGML_CATA_NOTATION;
2378  else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
2379  type = SGML_CATA_SGMLDECL;
2380  else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
2381  type = SGML_CATA_DOCUMENT;
2382  else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
2383  type = SGML_CATA_CATALOG;
2384  else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
2385  type = SGML_CATA_BASE;
2386  else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) {
2387  xmlFree(name);
2388  cur = xmlParseSGMLCatalogName(cur, &name);
2389  if (name == NULL) {
2390  /* error */
2391  break;
2392  }
2393  xmlFree(name);
2394  continue;
2395  }
2396  xmlFree(name);
2397  name = NULL;
2398 
2399  switch(type) {
2400  case SGML_CATA_ENTITY:
2401  if (*cur == '%')
2402  type = SGML_CATA_PENTITY;
2403  /* Falls through. */
2404  case SGML_CATA_PENTITY:
2405  case SGML_CATA_DOCTYPE:
2406  case SGML_CATA_LINKTYPE:
2407  case SGML_CATA_NOTATION:
2408  cur = xmlParseSGMLCatalogName(cur, &name);
2409  if (cur == NULL) {
2410  /* error */
2411  break;
2412  }
2413  if (!IS_BLANK_CH(*cur)) {
2414  /* error */
2415  break;
2416  }
2417  SKIP_BLANKS;
2418  cur = xmlParseSGMLCatalogPubid(cur, &sysid);
2419  if (cur == NULL) {
2420  /* error */
2421  break;
2422  }
2423  break;
2424  case SGML_CATA_PUBLIC:
2425  case SGML_CATA_SYSTEM:
2426  case SGML_CATA_DELEGATE:
2427  cur = xmlParseSGMLCatalogPubid(cur, &name);
2428  if (cur == NULL) {
2429  /* error */
2430  break;
2431  }
2432  if (type != SGML_CATA_SYSTEM) {
2433  xmlChar *normid;
2434 
2435  normid = xmlCatalogNormalizePublic(name);
2436  if (normid != NULL) {
2437  if (name != NULL)
2438  xmlFree(name);
2439  if (*normid != 0)
2440  name = normid;
2441  else {
2442  xmlFree(normid);
2443  name = NULL;
2444  }
2445  }
2446  }
2447  if (!IS_BLANK_CH(*cur)) {
2448  /* error */
2449  break;
2450  }
2451  SKIP_BLANKS;
2452  cur = xmlParseSGMLCatalogPubid(cur, &sysid);
2453  if (cur == NULL) {
2454  /* error */
2455  break;
2456  }
2457  break;
2458  case SGML_CATA_BASE:
2459  case SGML_CATA_CATALOG:
2460  case SGML_CATA_DOCUMENT:
2461  case SGML_CATA_SGMLDECL:
2462  cur = xmlParseSGMLCatalogPubid(cur, &sysid);
2463  if (cur == NULL) {
2464  /* error */
2465  break;
2466  }
2467  break;
2468  default:
2469  break;
2470  }
2471  if (cur == NULL) {
2472  if (name != NULL)
2473  xmlFree(name);
2474  if (sysid != NULL)
2475  xmlFree(sysid);
2476  break;
2477  } else if (type == SGML_CATA_BASE) {
2478  if (base != NULL)
2479  xmlFree(base);
2480  base = xmlStrdup(sysid);
2481  } else if ((type == SGML_CATA_PUBLIC) ||
2482  (type == SGML_CATA_SYSTEM)) {
2483  xmlChar *filename;
2484 
2485  filename = xmlBuildURI(sysid, base);
2486  if (filename != NULL) {
2487  xmlCatalogEntryPtr entry;
2488 
2489  entry = xmlNewCatalogEntry(type, name, filename,
2490  NULL, XML_CATA_PREFER_NONE, NULL);
2491  res = xmlHashAddEntry(catal->sgml, name, entry);
2492  if (res < 0) {
2493  xmlFreeCatalogEntry(entry, NULL);
2494  }
2495  xmlFree(filename);
2496  }
2497 
2498  } else if (type == SGML_CATA_CATALOG) {
2499  if (super) {
2500  xmlCatalogEntryPtr entry;
2501 
2502  entry = xmlNewCatalogEntry(type, sysid, NULL, NULL,
2503  XML_CATA_PREFER_NONE, NULL);
2504  res = xmlHashAddEntry(catal->sgml, sysid, entry);
2505  if (res < 0) {
2506  xmlFreeCatalogEntry(entry, NULL);
2507  }
2508  } else {
2509  xmlChar *filename;
2510 
2511  filename = xmlBuildURI(sysid, base);
2512  if (filename != NULL) {
2513  xmlExpandCatalog(catal, (const char *)filename);
2514  xmlFree(filename);
2515  }
2516  }
2517  }
2518  /*
2519  * drop anything else we won't handle it
2520  */
2521  if (name != NULL)
2522  xmlFree(name);
2523  if (sysid != NULL)
2524  xmlFree(sysid);
2525  }
2526  }
2527  if (base != NULL)
2528  xmlFree(base);
2529  if (cur == NULL)
2530  return(-1);
2531  return(0);
2532 }
2533 
2534 /************************************************************************
2535  * *
2536  * SGML Catalog handling *
2537  * *
2538  ************************************************************************/
2539 
2549 static const xmlChar *
2550 xmlCatalogGetSGMLPublic(xmlHashTablePtr catal, const xmlChar *pubID) {
2551  xmlCatalogEntryPtr entry;
2552  xmlChar *normid;
2553 
2554  if (catal == NULL)
2555  return(NULL);
2556 
2557  normid = xmlCatalogNormalizePublic(pubID);
2558  if (normid != NULL)
2559  pubID = (*normid != 0 ? normid : NULL);
2560 
2561  entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, pubID);
2562  if (entry == NULL) {
2563  if (normid != NULL)
2564  xmlFree(normid);
2565  return(NULL);
2566  }
2567  if (entry->type == SGML_CATA_PUBLIC) {
2568  if (normid != NULL)
2569  xmlFree(normid);
2570  return(entry->URL);
2571  }
2572  if (normid != NULL)
2573  xmlFree(normid);
2574  return(NULL);
2575 }
2576 
2586 static const xmlChar *
2587 xmlCatalogGetSGMLSystem(xmlHashTablePtr catal, const xmlChar *sysID) {
2588  xmlCatalogEntryPtr entry;
2589 
2590  if (catal == NULL)
2591  return(NULL);
2592 
2593  entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, sysID);
2594  if (entry == NULL)
2595  return(NULL);
2596  if (entry->type == SGML_CATA_SYSTEM)
2597  return(entry->URL);
2598  return(NULL);
2599 }
2600 
2611 static const xmlChar *
2612 xmlCatalogSGMLResolve(xmlCatalogPtr catal, const xmlChar *pubID,
2613  const xmlChar *sysID) {
2614  const xmlChar *ret = NULL;
2615 
2616  if (catal->sgml == NULL)
2617  return(NULL);
2618 
2619  if (pubID != NULL)
2620  ret = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
2621  if (ret != NULL)
2622  return(ret);
2623  if (sysID != NULL)
2624  ret = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
2625  if (ret != NULL)
2626  return(ret);
2627  return(NULL);
2628 }
2629 
2630 /************************************************************************
2631  * *
2632  * Specific Public interfaces *
2633  * *
2634  ************************************************************************/
2635 
2646 xmlCatalogPtr
2647 xmlLoadSGMLSuperCatalog(const char *filename)
2648 {
2649  xmlChar *content;
2650  xmlCatalogPtr catal;
2651  int ret;
2652 
2653  content = xmlLoadFileContent(filename);
2654  if (content == NULL)
2655  return(NULL);
2656 
2657  catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
2658  if (catal == NULL) {
2659  xmlFree(content);
2660  return(NULL);
2661  }
2662 
2663  ret = xmlParseSGMLCatalog(catal, content, filename, 1);
2664  xmlFree(content);
2665  if (ret < 0) {
2666  xmlFreeCatalog(catal);
2667  return(NULL);
2668  }
2669  return (catal);
2670 }
2671 
2683 xmlCatalogPtr
2684 xmlLoadACatalog(const char *filename)
2685 {
2686  xmlChar *content;
2687  xmlChar *first;
2688  xmlCatalogPtr catal;
2689  int ret;
2690 
2691  content = xmlLoadFileContent(filename);
2692  if (content == NULL)
2693  return(NULL);
2694 
2695 
2696  first = content;
2697 
2698  while ((*first != 0) && (*first != '-') && (*first != '<') &&
2699  (!(((*first >= 'A') && (*first <= 'Z')) ||
2700  ((*first >= 'a') && (*first <= 'z')))))
2701  first++;
2702 
2703  if (*first != '<') {
2704  catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
2705  if (catal == NULL) {
2706  xmlFree(content);
2707  return(NULL);
2708  }
2709  ret = xmlParseSGMLCatalog(catal, content, filename, 0);
2710  if (ret < 0) {
2711  xmlFreeCatalog(catal);
2712  xmlFree(content);
2713  return(NULL);
2714  }
2715  } else {
2716  catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
2717  if (catal == NULL) {
2718  xmlFree(content);
2719  return(NULL);
2720  }
2721  catal->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
2722  NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
2723  }
2724  xmlFree(content);
2725  return (catal);
2726 }
2727 
2738 static int
2739 xmlExpandCatalog(xmlCatalogPtr catal, const char *filename)
2740 {
2741  int ret;
2742 
2743  if ((catal == NULL) || (filename == NULL))
2744  return(-1);
2745 
2746 
2747  if (catal->type == XML_SGML_CATALOG_TYPE) {
2748  xmlChar *content;
2749 
2750  content = xmlLoadFileContent(filename);
2751  if (content == NULL)
2752  return(-1);
2753 
2754  ret = xmlParseSGMLCatalog(catal, content, filename, 0);
2755  if (ret < 0) {
2756  xmlFree(content);
2757  return(-1);
2758  }
2759  xmlFree(content);
2760  } else {
2761  xmlCatalogEntryPtr tmp, cur;
2762  tmp = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
2763  NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
2764 
2765  cur = catal->xml;
2766  if (cur == NULL) {
2767  catal->xml = tmp;
2768  } else {
2769  while (cur->next != NULL) cur = cur->next;
2770  cur->next = tmp;
2771  }
2772  }
2773  return (0);
2774 }
2775 
2786 xmlChar *
2787 xmlACatalogResolveSystem(xmlCatalogPtr catal, const xmlChar *sysID) {
2788  xmlChar *ret = NULL;
2789 
2790  if ((sysID == NULL) || (catal == NULL))
2791  return(NULL);
2792 
2793  if (xmlDebugCatalogs)
2795  "Resolve sysID %s\n", sysID);
2796 
2797  if (catal->type == XML_XML_CATALOG_TYPE) {
2798  ret = xmlCatalogListXMLResolve(catal->xml, NULL, sysID);
2799  if (ret == XML_CATAL_BREAK)
2800  ret = NULL;
2801  } else {
2802  const xmlChar *sgml;
2803 
2804  sgml = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
2805  if (sgml != NULL)
2806  ret = xmlStrdup(sgml);
2807  }
2808  return(ret);
2809 }
2810 
2821 xmlChar *
2822 xmlACatalogResolvePublic(xmlCatalogPtr catal, const xmlChar *pubID) {
2823  xmlChar *ret = NULL;
2824 
2825  if ((pubID == NULL) || (catal == NULL))
2826  return(NULL);
2827 
2828  if (xmlDebugCatalogs)
2830  "Resolve pubID %s\n", pubID);
2831 
2832  if (catal->type == XML_XML_CATALOG_TYPE) {
2833  ret = xmlCatalogListXMLResolve(catal->xml, pubID, NULL);
2834  if (ret == XML_CATAL_BREAK)
2835  ret = NULL;
2836  } else {
2837  const xmlChar *sgml;
2838 
2839  sgml = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
2840  if (sgml != NULL)
2841  ret = xmlStrdup(sgml);
2842  }
2843  return(ret);
2844 }
2845 
2857 xmlChar *
2858 xmlACatalogResolve(xmlCatalogPtr catal, const xmlChar * pubID,
2859  const xmlChar * sysID)
2860 {
2861  xmlChar *ret = NULL;
2862 
2863  if (((pubID == NULL) && (sysID == NULL)) || (catal == NULL))
2864  return (NULL);
2865 
2866  if (xmlDebugCatalogs) {
2867  if ((pubID != NULL) && (sysID != NULL)) {
2869  "Resolve: pubID %s sysID %s\n", pubID, sysID);
2870  } else if (pubID != NULL) {
2872  "Resolve: pubID %s\n", pubID);
2873  } else {
2875  "Resolve: sysID %s\n", sysID);
2876  }
2877  }
2878 
2879  if (catal->type == XML_XML_CATALOG_TYPE) {
2880  ret = xmlCatalogListXMLResolve(catal->xml, pubID, sysID);
2881  if (ret == XML_CATAL_BREAK)
2882  ret = NULL;
2883  } else {
2884  const xmlChar *sgml;
2885 
2886  sgml = xmlCatalogSGMLResolve(catal, pubID, sysID);
2887  if (sgml != NULL)
2888  ret = xmlStrdup(sgml);
2889  }
2890  return (ret);
2891 }
2892 
2903 xmlChar *
2904 xmlACatalogResolveURI(xmlCatalogPtr catal, const xmlChar *URI) {
2905  xmlChar *ret = NULL;
2906 
2907  if ((URI == NULL) || (catal == NULL))
2908  return(NULL);
2909 
2910  if (xmlDebugCatalogs)
2912  "Resolve URI %s\n", URI);
2913 
2914  if (catal->type == XML_XML_CATALOG_TYPE) {
2915  ret = xmlCatalogListXMLResolveURI(catal->xml, URI);
2916  if (ret == XML_CATAL_BREAK)
2917  ret = NULL;
2918  } else {
2919  const xmlChar *sgml;
2920 
2921  sgml = xmlCatalogSGMLResolve(catal, NULL, URI);
2922  if (sgml != NULL)
2923  ret = xmlStrdup(sgml);
2924  }
2925  return(ret);
2926 }
2927 
2928 #ifdef LIBXML_OUTPUT_ENABLED
2929 
2936 void
2937 xmlACatalogDump(xmlCatalogPtr catal, FILE *out) {
2938  if ((out == NULL) || (catal == NULL))
2939  return;
2940 
2941  if (catal->type == XML_XML_CATALOG_TYPE) {
2942  xmlDumpXMLCatalog(out, catal->xml);
2943  } else {
2944  xmlHashScan(catal->sgml, xmlCatalogDumpEntry, out);
2945  }
2946 }
2947 #endif /* LIBXML_OUTPUT_ENABLED */
2948 
2961 int
2962 xmlACatalogAdd(xmlCatalogPtr catal, const xmlChar * type,
2963  const xmlChar * orig, const xmlChar * replace)
2964 {
2965  int res = -1;
2966 
2967  if (catal == NULL)
2968  return(-1);
2969 
2970  if (catal->type == XML_XML_CATALOG_TYPE) {
2971  res = xmlAddXMLCatalog(catal->xml, type, orig, replace);
2972  } else {
2973  xmlCatalogEntryType cattype;
2974 
2975  cattype = xmlGetSGMLCatalogEntryType(type);
2976  if (cattype != XML_CATA_NONE) {
2977  xmlCatalogEntryPtr entry;
2978 
2979  entry = xmlNewCatalogEntry(cattype, orig, replace, NULL,
2980  XML_CATA_PREFER_NONE, NULL);
2981  if (catal->sgml == NULL)
2982  catal->sgml = xmlHashCreate(10);
2983  res = xmlHashAddEntry(catal->sgml, orig, entry);
2984  }
2985  }
2986  return (res);
2987 }
2988 
2998 int
2999 xmlACatalogRemove(xmlCatalogPtr catal, const xmlChar *value) {
3000  int res = -1;
3001 
3002  if ((catal == NULL) || (value == NULL))
3003  return(-1);
3004 
3005  if (catal->type == XML_XML_CATALOG_TYPE) {
3006  res = xmlDelXMLCatalog(catal->xml, value);
3007  } else {
3008  res = xmlHashRemoveEntry(catal->sgml, value, xmlFreeCatalogEntry);
3009  if (res == 0)
3010  res = 1;
3011  }
3012  return(res);
3013 }
3014 
3023 xmlCatalogPtr
3024 xmlNewCatalog(int sgml) {
3025  xmlCatalogPtr catal = NULL;
3026 
3027  if (sgml) {
3028  catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE,
3029  xmlCatalogDefaultPrefer);
3030  if ((catal != NULL) && (catal->sgml == NULL))
3031  catal->sgml = xmlHashCreate(10);
3032  } else
3033  catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
3034  xmlCatalogDefaultPrefer);
3035  return(catal);
3036 }
3037 
3046 int
3047 xmlCatalogIsEmpty(xmlCatalogPtr catal) {
3048  if (catal == NULL)
3049  return(-1);
3050 
3051  if (catal->type == XML_XML_CATALOG_TYPE) {
3052  if (catal->xml == NULL)
3053  return(1);
3054  if ((catal->xml->type != XML_CATA_CATALOG) &&
3055  (catal->xml->type != XML_CATA_BROKEN_CATALOG))
3056  return(-1);
3057  if (catal->xml->children == NULL)
3058  return(1);
3059  return(0);
3060  } else {
3061  int res;
3062 
3063  if (catal->sgml == NULL)
3064  return(1);
3065  res = xmlHashSize(catal->sgml);
3066  if (res == 0)
3067  return(1);
3068  if (res < 0)
3069  return(-1);
3070  }
3071  return(0);
3072 }
3073 
3074 /************************************************************************
3075  * *
3076  * Public interfaces manipulating the global shared default catalog *
3077  * *
3078  ************************************************************************/
3079 
3088 static void
3089 xmlInitializeCatalogData(void) {
3090  if (xmlCatalogInitialized != 0)
3091  return;
3092 
3093  if (getenv("XML_DEBUG_CATALOG"))
3094  xmlDebugCatalogs = 1;
3095  xmlCatalogMutex = xmlNewRMutex();
3096 
3097  xmlCatalogInitialized = 1;
3098 }
3106 void
3107 xmlInitializeCatalog(void) {
3108  if (xmlCatalogInitialized != 0)
3109  return;
3110 
3111  xmlInitializeCatalogData();
3112  xmlRMutexLock(xmlCatalogMutex);
3113 
3114  if (getenv("XML_DEBUG_CATALOG"))
3115  xmlDebugCatalogs = 1;
3116 
3117  if (xmlDefaultCatalog == NULL) {
3118  const char *catalogs;
3119  char *path;
3120  const char *cur, *paths;
3121  xmlCatalogPtr catal;
3122  xmlCatalogEntryPtr *nextent;
3123 
3124  catalogs = (const char *) getenv("XML_CATALOG_FILES");
3125  if (catalogs == NULL)
3126 #if defined(_WIN32) && defined(_MSC_VER)
3127  {
3128  void* hmodule;
3129  hmodule = GetModuleHandleA("libxml2.dll");
3130  if (hmodule == NULL)
3132  if (hmodule != NULL) {
3133  char buf[256];
3134  unsigned long len = GetModuleFileNameA(hmodule, buf, 255);
3135  if (len != 0) {
3136  char* p = &(buf[len]);
3137  while (*p != '\\' && p > buf)
3138  p--;
3139  if (p != buf) {
3140  xmlChar* uri;
3141  strncpy(p, "\\..\\etc\\catalog", 255 - (p - buf));
3142  uri = xmlCanonicPath((const xmlChar*)buf);
3143  if (uri != NULL) {
3145  xmlFree(uri);
3146  }
3147  }
3148  }
3149  }
3150  catalogs = XML_XML_DEFAULT_CATALOG;
3151  }
3152 #else
3153  catalogs = XML_XML_DEFAULT_CATALOG;
3154 #endif
3155 
3156  catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
3157  xmlCatalogDefaultPrefer);
3158  if (catal != NULL) {
3159  /* the XML_CATALOG_FILES envvar is allowed to contain a
3160  space-separated list of entries. */
3161  cur = catalogs;
3162  nextent = &catal->xml;
3163  while (*cur != '\0') {
3164  while (xmlIsBlank_ch(*cur))
3165  cur++;
3166  if (*cur != 0) {
3167  paths = cur;
3168  while ((*cur != 0) && (!xmlIsBlank_ch(*cur)))
3169  cur++;
3170  path = (char *) xmlStrndup((const xmlChar *)paths, cur - paths);
3171  if (path != NULL) {
3172  *nextent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
3173  NULL, BAD_CAST path, xmlCatalogDefaultPrefer, NULL);
3174  if (*nextent != NULL)
3175  nextent = &((*nextent)->next);
3176  xmlFree(path);
3177  }
3178  }
3179  }
3180  xmlDefaultCatalog = catal;
3181  }
3182  }
3183 
3184  xmlRMutexUnlock(xmlCatalogMutex);
3185 }
3186 
3187 
3199 int
3200 xmlLoadCatalog(const char *filename)
3201 {
3202  int ret;
3203  xmlCatalogPtr catal;
3204 
3205  if (!xmlCatalogInitialized)
3206  xmlInitializeCatalogData();
3207 
3208  xmlRMutexLock(xmlCatalogMutex);
3209 
3210  if (xmlDefaultCatalog == NULL) {
3211  catal = xmlLoadACatalog(filename);
3212  if (catal == NULL) {
3213  xmlRMutexUnlock(xmlCatalogMutex);
3214  return(-1);
3215  }
3216 
3217  xmlDefaultCatalog = catal;
3218  xmlRMutexUnlock(xmlCatalogMutex);
3219  return(0);
3220  }
3221 
3222  ret = xmlExpandCatalog(xmlDefaultCatalog, filename);
3223  xmlRMutexUnlock(xmlCatalogMutex);
3224  return(ret);
3225 }
3226 
3236 void
3237 xmlLoadCatalogs(const char *pathss) {
3238  const char *cur;
3239  const char *paths;
3240  xmlChar *path;
3241 #ifdef _WIN32
3242  int i, iLen;
3243 #endif
3244 
3245  if (pathss == NULL)
3246  return;
3247 
3248  cur = pathss;
3249  while (*cur != 0) {
3250  while (xmlIsBlank_ch(*cur)) cur++;
3251  if (*cur != 0) {
3252  paths = cur;
3253  while ((*cur != 0) && (*cur != PATH_SEPARATOR) && (!xmlIsBlank_ch(*cur)))
3254  cur++;
3255  path = xmlStrndup((const xmlChar *)paths, cur - paths);
3256  if (path != NULL) {
3257 #ifdef _WIN32
3258  iLen = strlen((const char*)path);
3259  for(i = 0; i < iLen; i++) {
3260  if(path[i] == '\\') {
3261  path[i] = '/';
3262  }
3263  }
3264 #endif
3265  xmlLoadCatalog((const char *) path);
3266  xmlFree(path);
3267  }
3268  }
3269  while (*cur == PATH_SEPARATOR)
3270  cur++;
3271  }
3272 }
3273 
3279 void
3280 xmlCatalogCleanup(void) {
3281  if (xmlCatalogInitialized == 0)
3282  return;
3283 
3284  xmlRMutexLock(xmlCatalogMutex);
3285  if (xmlDebugCatalogs)
3287  "Catalogs cleanup\n");
3288  if (xmlCatalogXMLFiles != NULL)
3289  xmlHashFree(xmlCatalogXMLFiles, xmlFreeCatalogHashEntryList);
3290  xmlCatalogXMLFiles = NULL;
3291  if (xmlDefaultCatalog != NULL)
3292  xmlFreeCatalog(xmlDefaultCatalog);
3293  xmlDefaultCatalog = NULL;
3294  xmlDebugCatalogs = 0;
3295  xmlCatalogInitialized = 0;
3296  xmlRMutexUnlock(xmlCatalogMutex);
3297  xmlFreeRMutex(xmlCatalogMutex);
3298 }
3299 
3309 xmlChar *
3310 xmlCatalogResolveSystem(const xmlChar *sysID) {
3311  xmlChar *ret;
3312 
3313  if (!xmlCatalogInitialized)
3314  xmlInitializeCatalog();
3315 
3316  ret = xmlACatalogResolveSystem(xmlDefaultCatalog, sysID);
3317  return(ret);
3318 }
3319 
3329 xmlChar *
3330 xmlCatalogResolvePublic(const xmlChar *pubID) {
3331  xmlChar *ret;
3332 
3333  if (!xmlCatalogInitialized)
3334  xmlInitializeCatalog();
3335 
3336  ret = xmlACatalogResolvePublic(xmlDefaultCatalog, pubID);
3337  return(ret);
3338 }
3339 
3350 xmlChar *
3351 xmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) {
3352  xmlChar *ret;
3353 
3354  if (!xmlCatalogInitialized)
3355  xmlInitializeCatalog();
3356 
3357  ret = xmlACatalogResolve(xmlDefaultCatalog, pubID, sysID);
3358  return(ret);
3359 }
3360 
3370 xmlChar *
3371 xmlCatalogResolveURI(const xmlChar *URI) {
3372  xmlChar *ret;
3373 
3374  if (!xmlCatalogInitialized)
3375  xmlInitializeCatalog();
3376 
3377  ret = xmlACatalogResolveURI(xmlDefaultCatalog, URI);
3378  return(ret);
3379 }
3380 
3381 #ifdef LIBXML_OUTPUT_ENABLED
3382 
3388 void
3389 xmlCatalogDump(FILE *out) {
3390  if (out == NULL)
3391  return;
3392 
3393  if (!xmlCatalogInitialized)
3394  xmlInitializeCatalog();
3395 
3396  xmlACatalogDump(xmlDefaultCatalog, out);
3397 }
3398 #endif /* LIBXML_OUTPUT_ENABLED */
3399 
3413 int
3414 xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) {
3415  int res = -1;
3416 
3417  if (!xmlCatalogInitialized)
3418  xmlInitializeCatalogData();
3419 
3420  xmlRMutexLock(xmlCatalogMutex);
3421  /*
3422  * Specific case where one want to override the default catalog
3423  * put in place by xmlInitializeCatalog();
3424  */
3425  if ((xmlDefaultCatalog == NULL) &&
3426  (xmlStrEqual(type, BAD_CAST "catalog"))) {
3427  xmlDefaultCatalog = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
3428  xmlCatalogDefaultPrefer);
3429  if (xmlDefaultCatalog != NULL) {
3430  xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
3431  orig, NULL, xmlCatalogDefaultPrefer, NULL);
3432  }
3433  xmlRMutexUnlock(xmlCatalogMutex);
3434  return(0);
3435  }
3436 
3437  res = xmlACatalogAdd(xmlDefaultCatalog, type, orig, replace);
3438  xmlRMutexUnlock(xmlCatalogMutex);
3439  return(res);
3440 }
3441 
3450 int
3451 xmlCatalogRemove(const xmlChar *value) {
3452  int res;
3453 
3454  if (!xmlCatalogInitialized)
3455  xmlInitializeCatalog();
3456 
3457  xmlRMutexLock(xmlCatalogMutex);
3458  res = xmlACatalogRemove(xmlDefaultCatalog, value);
3459  xmlRMutexUnlock(xmlCatalogMutex);
3460  return(res);
3461 }
3462 
3470 int
3471 xmlCatalogConvert(void) {
3472  int res = -1;
3473 
3474  if (!xmlCatalogInitialized)
3475  xmlInitializeCatalog();
3476 
3477  xmlRMutexLock(xmlCatalogMutex);
3478  res = xmlConvertSGMLCatalog(xmlDefaultCatalog);
3479  xmlRMutexUnlock(xmlCatalogMutex);
3480  return(res);
3481 }
3482 
3483 /************************************************************************
3484  * *
3485  * Public interface manipulating the common preferences *
3486  * *
3487  ************************************************************************/
3488 
3497 xmlCatalogAllow
3498 xmlCatalogGetDefaults(void) {
3499  return(xmlCatalogDefaultAllow);
3500 }
3501 
3509 void
3510 xmlCatalogSetDefaults(xmlCatalogAllow allow) {
3511  if (xmlDebugCatalogs) {
3512  switch (allow) {
3513  case XML_CATA_ALLOW_NONE:
3515  "Disabling catalog usage\n");
3516  break;
3517  case XML_CATA_ALLOW_GLOBAL:
3519  "Allowing only global catalogs\n");
3520  break;
3521  case XML_CATA_ALLOW_DOCUMENT:
3523  "Allowing only catalogs from the document\n");
3524  break;
3525  case XML_CATA_ALLOW_ALL:
3527  "Allowing all catalogs\n");
3528  break;
3529  }
3530  }
3531  xmlCatalogDefaultAllow = allow;
3532 }
3533 
3544 xmlCatalogPrefer
3545 xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) {
3546  xmlCatalogPrefer ret = xmlCatalogDefaultPrefer;
3547 
3548  if (prefer == XML_CATA_PREFER_NONE)
3549  return(ret);
3550 
3551  if (xmlDebugCatalogs) {
3552  switch (prefer) {
3553  case XML_CATA_PREFER_PUBLIC:
3555  "Setting catalog preference to PUBLIC\n");
3556  break;
3557  case XML_CATA_PREFER_SYSTEM:
3559  "Setting catalog preference to SYSTEM\n");
3560  break;
3561  default:
3562  return(ret);
3563  }
3564  }
3565  xmlCatalogDefaultPrefer = prefer;
3566  return(ret);
3567 }
3568 
3578 int
3579 xmlCatalogSetDebug(int level) {
3580  int ret = xmlDebugCatalogs;
3581 
3582  if (level <= 0)
3583  xmlDebugCatalogs = 0;
3584  else
3585  xmlDebugCatalogs = level;
3586  return(ret);
3587 }
3588 
3589 /************************************************************************
3590  * *
3591  * Minimal interfaces used for per-document catalogs by the parser *
3592  * *
3593  ************************************************************************/
3594 
3601 void
3602 xmlCatalogFreeLocal(void *catalogs) {
3603  xmlCatalogEntryPtr catal;
3604 
3605  if (!xmlCatalogInitialized)
3606  xmlInitializeCatalog();
3607 
3608  catal = (xmlCatalogEntryPtr) catalogs;
3609  if (catal != NULL)
3610  xmlFreeCatalogEntryList(catal);
3611 }
3612 
3613 
3623 void *
3624 xmlCatalogAddLocal(void *catalogs, const xmlChar *URL) {
3625  xmlCatalogEntryPtr catal, add;
3626 
3627  if (!xmlCatalogInitialized)
3628  xmlInitializeCatalog();
3629 
3630  if (URL == NULL)
3631  return(catalogs);
3632 
3633  if (xmlDebugCatalogs)
3635  "Adding document catalog %s\n", URL);
3636 
3637  add = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, URL, NULL,
3638  xmlCatalogDefaultPrefer, NULL);
3639  if (add == NULL)
3640  return(catalogs);
3641 
3642  catal = (xmlCatalogEntryPtr) catalogs;
3643  if (catal == NULL)
3644  return((void *) add);
3645 
3646  while (catal->next != NULL)
3647  catal = catal->next;
3648  catal->next = add;
3649  return(catalogs);
3650 }
3651 
3664 xmlChar *
3665 xmlCatalogLocalResolve(void *catalogs, const xmlChar *pubID,
3666  const xmlChar *sysID) {
3667  xmlCatalogEntryPtr catal;
3668  xmlChar *ret;
3669 
3670  if (!xmlCatalogInitialized)
3671  xmlInitializeCatalog();
3672 
3673  if ((pubID == NULL) && (sysID == NULL))
3674  return(NULL);
3675 
3676  if (xmlDebugCatalogs) {
3677  if ((pubID != NULL) && (sysID != NULL)) {
3679  "Local Resolve: pubID %s sysID %s\n", pubID, sysID);
3680  } else if (pubID != NULL) {
3682  "Local Resolve: pubID %s\n", pubID);
3683  } else {
3685  "Local Resolve: sysID %s\n", sysID);
3686  }
3687  }
3688 
3689  catal = (xmlCatalogEntryPtr) catalogs;
3690  if (catal == NULL)
3691  return(NULL);
3692  ret = xmlCatalogListXMLResolve(catal, pubID, sysID);
3693  if ((ret != NULL) && (ret != XML_CATAL_BREAK))
3694  return(ret);
3695  return(NULL);
3696 }
3697 
3709 xmlChar *
3710 xmlCatalogLocalResolveURI(void *catalogs, const xmlChar *URI) {
3711  xmlCatalogEntryPtr catal;
3712  xmlChar *ret;
3713 
3714  if (!xmlCatalogInitialized)
3715  xmlInitializeCatalog();
3716 
3717  if (URI == NULL)
3718  return(NULL);
3719 
3720  if (xmlDebugCatalogs)
3722  "Resolve URI %s\n", URI);
3723 
3724  catal = (xmlCatalogEntryPtr) catalogs;
3725  if (catal == NULL)
3726  return(NULL);
3727  ret = xmlCatalogListXMLResolveURI(catal, URI);
3728  if ((ret != NULL) && (ret != XML_CATAL_BREAK))
3729  return(ret);
3730  return(NULL);
3731 }
3732 
3733 /************************************************************************
3734  * *
3735  * Deprecated interfaces *
3736  * *
3737  ************************************************************************/
3747 const xmlChar *
3748 xmlCatalogGetSystem(const xmlChar *sysID) {
3749  xmlChar *ret;
3750  static xmlChar result[1000];
3751  static int msg = 0;
3752 
3753  if (!xmlCatalogInitialized)
3754  xmlInitializeCatalog();
3755 
3756  if (msg == 0) {
3758  "Use of deprecated xmlCatalogGetSystem() call\n");
3759  msg++;
3760  }
3761 
3762  if (sysID == NULL)
3763  return(NULL);
3764 
3765  /*
3766  * Check first the XML catalogs
3767  */
3768  if (xmlDefaultCatalog != NULL) {
3769  ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, NULL, sysID);
3770  if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
3771  snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
3772  result[sizeof(result) - 1] = 0;
3773  return(result);
3774  }
3775  }
3776 
3777  if (xmlDefaultCatalog != NULL)
3778  return(xmlCatalogGetSGMLSystem(xmlDefaultCatalog->sgml, sysID));
3779  return(NULL);
3780 }
3781 
3791 const xmlChar *
3792 xmlCatalogGetPublic(const xmlChar *pubID) {
3793  xmlChar *ret;
3794  static xmlChar result[1000];
3795  static int msg = 0;
3796 
3797  if (!xmlCatalogInitialized)
3798  xmlInitializeCatalog();
3799 
3800  if (msg == 0) {
3802  "Use of deprecated xmlCatalogGetPublic() call\n");
3803  msg++;
3804  }
3805 
3806  if (pubID == NULL)
3807  return(NULL);
3808 
3809  /*
3810  * Check first the XML catalogs
3811  */
3812  if (xmlDefaultCatalog != NULL) {
3813  ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, pubID, NULL);
3814  if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
3815  snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
3816  result[sizeof(result) - 1] = 0;
3817  return(result);
3818  }
3819  }
3820 
3821  if (xmlDefaultCatalog != NULL)
3822  return(xmlCatalogGetSGMLPublic(xmlDefaultCatalog->sgml, pubID));
3823  return(NULL);
3824 }
3825 
3826 #define bottom_catalog
3827 #include "elfgcchack.h"
3828 #endif /* LIBXML_CATALOG_ENABLED */
XMLPUBFUN void XMLCALL xmlFreeNs(xmlNsPtr cur)
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href)
XMLPUBVAR xmlMallocFunc xmlMallocAtomic
Definition: globals.h:248
GLint level
Definition: gl.h:1546
XMLPUBFUN int XMLCALL xmlHashSize(xmlHashTablePtr table)
Definition: hash.c:1039
XMLPUBFUN int XMLCALL xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name, xmlHashDeallocator f)
Definition: hash.c:1057
XMLPUBFUN xmlRMutexPtr XMLCALL xmlNewRMutex(void)
Definition: threads.c:285
Definition: pdh_main.c:93
#define XML_XML_DEFAULT_CATALOG
Definition: xmllint.c:90
XMLPUBFUN xmlDtdPtr XMLCALL xmlNewDtd(xmlDocPtr doc, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID)
XMLPUBFUN void XMLCALL xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data)
Definition: hash.c:864
#define error(str)
Definition: mkdosfs.c:1605
GLuint64EXT * result
Definition: glext.h:11304
XMLPUBFUN void XMLCALL xmlRMutexLock(xmlRMutexPtr tok)
Definition: threads.c:343
#define open
Definition: acwin.h:95
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
XMLPUBFUN int XMLCALL xmlGetThreadId(void)
Definition: threads.c:764
GLsizei const GLchar ** path
Definition: glext.h:7234
const char * uri
Definition: sec_mgr.c:1588
Definition: tree.h:389
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:41
#define NEXT(n, i)
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
GLuint GLuint GLsizei count
Definition: gl.h:1545
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:425
void dealloc(int i, int no_throw)
Definition: ehthrow.cxx:33
errorSAXFunc error
Definition: parser.h:785
int pedantic
Definition: parser.h:257
const GLint * first
Definition: glext.h:5794
XMLPUBFUN char *XMLCALL xmlParserGetDirectory(const char *filename)
XMLPUBFUN xmlChar *XMLCALL xmlGetProp(const xmlNode *node, const xmlChar *name)
XMLPUBFUN int XMLCALL inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
Definition: parser.c:1752
#define snprintf
Definition: wintirpc.h:48
#define PATH_SEPARATOR
Definition: xmllint.c:211
XMLPUBFUN void XMLCALL xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
XMLPUBFUN int XMLCALL xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata)
Definition: hash.c:394
static int fd
Definition: io.c:51
int xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input)
Definition: buf.c:1285
XMLPUBFUN xmlChar *XMLCALL xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur)
const char * filename
Definition: ioapi.h:135
xmlNs * nsDef
Definition: tree.h:504
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
Definition: tree.h:406
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
struct node node
_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)
XMLPUBFUN void XMLCALL xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f)
Definition: hash.c:327
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
xmlOutputBuffer * xmlOutputBufferPtr
Definition: tree.h:32
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:529
#define IS_BLANK_CH(c)
static HMODULE hmodule
Definition: rasapi.c:29
content
Definition: atl_ax.c:993
XMLPUBVAR xmlGenericErrorFunc xmlGenericError
Definition: globals.h:346
XMLPUBFUN xmlChar *XMLCALL xmlBuildURI(const xmlChar *URI, const xmlChar *base)
Definition: uri.c:1891
XMLPUBFUN xmlChar *XMLCALL xmlCanonicPath(const xmlChar *path)
Definition: uri.c:2379
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
#define XML_XML_NAMESPACE
Definition: tree.h:140
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:249
int validate
Definition: parser.h:222
#define LIBXML_ATTR_FORMAT(fmt, args)
Definition: xmlversion.h:477
INT replace(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], DWORD dwFlags, BOOL *doMore)
Definition: replace.c:47
GLboolean GLuint group
Definition: glext.h:11120
#define SEEK_SET
Definition: jmemansi.c:26
GLsizeiptr size
Definition: glext.h:5919
XMLPUBFUN xmlNodePtr XMLCALL xmlAddChild(xmlNodePtr parent, xmlNodePtr cur)
int wellFormed
Definition: parser.h:190
Definition: id3.c:95
r parent
Definition: btrfs.c:2944
const GLubyte * c
Definition: glext.h:8905
XMLPUBVAR xmlSAXHandlerV1 xmlDefaultSAXHandler
Definition: globals.h:321
static FILE * out
Definition: regtests2xml.c:44
XMLPUBFUN void XMLCALL xmlFreeDoc(xmlDocPtr cur)
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
XMLPUBFUN xmlChar *XMLCALL xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace)
XMLPUBFUN void XMLCALL xmlRMutexUnlock(xmlRMutexPtr tok)
Definition: threads.c:388
#define __stdcall
Definition: typedefs.h:25
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
#define IS_PUBIDCHAR_CH(c)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
XMLPUBFUN int XMLCALL xmlParseDocument(xmlParserCtxtPtr ctxt)
Definition: parser.c:10689
XMLPUBFUN xmlHashTablePtr XMLCALL xmlHashCreate(int size)
Definition: hash.c:181
Definition: tree.h:489
XMLPUBFUN xmlParserInputBufferPtr XMLCALL xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc)
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
int ret
xmlDocPtr myDoc
Definition: parser.h:189
Definition: mxnamespace.c:44
#define xmlIsBlank_ch(c)
Definition: chvalid.h:88
Definition: stat.h:55
uint32_t entry
Definition: isohybrid.c:63
unsigned char xmlChar
Definition: xmlstring.h:28
GLenum GLsizei len
Definition: glext.h:6722
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
XMLPUBFUN int XMLCALL xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len)
Definition: xmlstring.c:212
GLsizei const GLfloat * value
Definition: glext.h:6069
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
int loadsubset
Definition: parser.h:260
#define close
Definition: acwin.h:98
int dictNames
Definition: parser.h:294
XMLPUBFUN xmlNsPtr XMLCALL xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix)
GLsizei const GLuint * paths
Definition: glext.h:11717
FxCollectionEntry * cur
xmlParserInputBufferPtr buf
Definition: parser.h:56
#define IS_LETTER(c)
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
const char * filename
Definition: parser.h:58
static unsigned __int64 next
Definition: rand_nt.c:6
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
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
struct define * next
Definition: compiler.c:65
#define ok(value,...)
Definition: atltest.h:57
#define ATTRIBUTE_UNUSED
Definition: win32config.h:132
#define NULL
Definition: types.h:112
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name, const xmlChar *content)
#define XML_MAX_NAMELEN
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:247
char * directory
Definition: parser.h:228
Definition: tree.h:551
#define msg(x)
Definition: auth_time.c:54
#define IS_DIGIT(c)
#define EOF
Definition: stdio.h:24
Definition: name.c:38
GLuint res
Definition: glext.h:9613
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement(const xmlDoc *doc)
#define c
Definition: ke_i.h:80
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
#define const
Definition: zconf.h:230
#define SEEK_END
Definition: cabinet.c:27
XMLPUBFUN void *XMLCALL xmlHashLookup(xmlHashTablePtr table, const xmlChar *name)
Definition: hash.c:466
XMLPUBFUN xmlParserCtxtPtr XMLCALL xmlNewParserCtxt(void)
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:159
GLfloat GLfloat p
Definition: glext.h:8902
#define memset(x, y, z)
Definition: compat.h:39
XMLPUBFUN void XMLCALL xmlFreeRMutex(xmlRMutexPtr tok)
Definition: threads.c:319
XMLPUBFUN xmlDocPtr XMLCALL xmlNewDoc(const xmlChar *version)
#define RAW(x)
Definition: genincdata.c:42
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:66
XMLPUBFUN xmlParserInputPtr XMLCALL xmlNewInputStream(xmlParserCtxtPtr ctxt)
#define SKIP_BLANKS
Definition: pattern.c:1266
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define SKIP(val)
Definition: pattern.c:1262
Definition: dlist.c:348
XMLPUBVAR void * xmlGenericErrorContext
Definition: globals.h:362
#define O_RDONLY
Definition: acwin.h:108
Definition: fci.c:126
GLuint const GLchar * name
Definition: glext.h:6031