Hello guys,

some months back, somebody complained that gnustep-base took ages for
them to build on a machine without network access. The problem was that
the gsdoc DTDs were not yet installed and autogsdoc was trying to fetch
them over the net, making it wait for a timeouts quite a while.
libxml2 does support a feature called xml-catalogs for such situations,
allowing you to remap xml PUBLIC/SYSTEM identifiers to new (local)
urls.

Recently, I took a look at GSXML and how it does handle DTD resolution.
It turns out that it is overriding DTD resolution in a manner that
bypasses catalogs. If a DTD is not installed to a location we explicitly
search, it will always be fetched from the original url. Attached is a
patch that corrects that by adding the DTDs GNUstep is resolving
internally to the catalog and running libxml2's builtin lookup function
afterwards. In theory, this should not break anything, but as always I
might have screwed up slightly somewhere.

Cheers,


Niels
Index: Source/Additions/GSXML.m
===================================================================
--- Source/Additions/GSXML.m	(revision 29650)
+++ Source/Additions/GSXML.m	(working copy)
@@ -77,6 +77,7 @@
 #include <libxml/entities.h>
 #include <libxml/parser.h>
 #include <libxml/parserInternals.h>
+#include <libxml/catalog.h>
 #ifdef	HAVE_LIBXML_SAX2_H
 #include <libxml/SAX2.h>
 #else
@@ -84,6 +85,7 @@
 # define	xmlSAX2GetLineNumber	getLineNumber
 # define	xmlSAX2GetPublicId	getPublicId
 # define	xmlSAX2GetSystemId	getSystemId
+# define	xmlSAX2ResolveEntity 	resolveEntity
 #endif
 #include <libxml/HTMLparser.h>
 #include <libxml/xmlmemory.h>
@@ -154,6 +156,7 @@
     {
       cacheDone = YES;
       xmlMemSetup(objc_free, objc_malloc, objc_realloc, objc_strdup);
+      xmlInitializeCatalog();
 
 #if	HAVE_LIBXML_SAX2_H
       xmlDefaultSAXHandlerInit();
@@ -2417,9 +2420,7 @@
 loadEntityFunction(void *ctx,
   const unsigned char *eid, const unsigned char *url)
 {
-  extern xmlParserInputPtr	xmlNewInputFromFile();
   NSString			*file = nil;
-  xmlParserInputPtr		ret = 0;
   NSString			*entityId;
   NSString			*location;
   NSArray			*components;
@@ -2428,10 +2429,10 @@
   unsigned			index;
 
   NSCAssert(ctx, @"No Context");
-  if (url == 0)
-    return 0;
+  if (url == NULL)
+    return NULL;
 
-  entityId = (eid != 0) ? (id)UTF8Str(eid) : nil;
+  entityId = (eid != NULL) ? (id)UTF8Str(eid) : nil;
   location = UTF8Str(url);
   components = [location pathComponents];
   local = (NSMutableString *) [NSMutableString string];
@@ -2574,51 +2575,24 @@
 					       ofType: @""
 					  inDirectory: @"DTDs"];
 	    }
-	  if (file == nil)
-	    {
-	      NSURL	*aURL;
-
-	      aURL = [NSURL URLWithString: location];
-	      if ([aURL isFileURL] == YES)
-	        {
-		  file = [aURL path];
-		}
-	      else
-	        {
-		  NSData	*data = [aURL resourceDataUsingCache: NO];
-
-		  if ([data length] > 0)
-		    {
-		      file = [@"/tmp" stringByAppendingPathComponent: local];
-		      [data writeToFile: file atomically: NO];
-		    }
-		}
-	    }
 	}
     }
 
+  /*
+   * If we found the DTD somewhere, add it to the catalog.
+   */
   if ([file length] > 0)
     {
-      const char	*path;
-
-#if	defined(__MINGW32__)
-      /*
-       * The xmlNewInputFromFile() function requires an eight bit string
-       * but on a modern windows filesystem the file name could be unicode
-       * which can't be represented as a cString ... and may cause an
-       * exception ... nothing we can do about it really.
-       */
-      path = [file cString];
-#else
-      path = [file fileSystemRepresentation];
-#endif
-      ret = xmlNewInputFromFile((xmlParserCtxtPtr)ctx, path);
+      NSURL *theURL = [NSURL fileURLWithPath: file];
+      xmlCatalogAdd((const unsigned char*)"public", eid,
+        UTF8STRING([theURL absoluteString]));
     }
-  else
-    {
-      NSLog(@"don't know how to load entity '%s' id '%s'", url, eid);
-    }
-  return ret;
+    
+  /*
+   * A local DTD will now be in the catalog: The builtin entity resolver can
+   * take over.
+   */
+  return xmlSAX2ResolveEntity(ctx, eid, url);
 }
 
 

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Gnustep-dev mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/gnustep-dev

Reply via email to