]> err.no Git - sope/blob - sope-xml/libxmlSAXDriver/libxmlSAXDriver.m
fixed samples makefile for compilation, some cleanups
[sope] / sope-xml / libxmlSAXDriver / libxmlSAXDriver.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include "libxmlSAXDriver.h"
24 #include "libxmlSAXLocator.h"
25 #include "TableCallbacks.h"
26 #include <SaxObjC/SaxException.h>
27 #include <SaxObjC/SaxAttributes.h>
28 #include "common.h"
29
30 #include <libxml/parser.h>
31
32 /*
33   TODO: xmlChar is really UTF-8, not cString !!!
34 */
35
36 static NSString *SaxDeclHandlerProperty =
37   @"http://xml.org/sax/properties/declaration-handler";
38 static NSString *SaxLexicalHandlerProperty =
39   @"http://xml.org/sax/properties/lexical-handler";
40 #if 0
41 static NSString *SaxDOMNodeProperty =
42   @"http://xml.org/sax/properties/dom-node";
43 static NSString *SaxXMLStringProperty =
44   @"http://xml.org/sax/properties/xml-string";
45 #endif
46
47 static int _UTF8ToUTF16(unsigned char **sourceStart, unsigned char *sourceEnd, 
48                         unichar **targetStart, const unichar *targetEnd);
49
50 static NSMapTable *uniqueStrings = NULL; // THREAD
51 static Class NSStringClass = Nil;
52
53 static inline NSString *xmlCharsToString(const xmlChar *_s) {
54   NSString *s;
55   char *newkey;
56   
57   if (_s == NULL) return nil;
58   
59   if (uniqueStrings == NULL) {
60     uniqueStrings = NSCreateMapTable(libxmlNonOwnedCStringMapKeyCallBacks,
61                                      NSObjectMapValueCallBacks,
62                                      128);
63   }
64   else if ((s = NSMapGet(uniqueStrings, _s))) {
65     /* found a string in cache ... */
66     return [s retain];
67   }
68
69   newkey = malloc(strlen(_s) + 1);
70   strcpy(newkey, _s);
71   
72   if (NSStringClass == Nil)
73     NSStringClass = [NSString class];
74   
75   s = [[NSStringClass alloc] initWithUTF8String:_s];
76   NSMapInsert(uniqueStrings, newkey, s);
77   return s;
78 }
79
80 extern xmlParserCtxtPtr xmlCreateMemoryParserCtxt(char *buffer, int size);
81
82 @implementation libxmlSAXDriver
83
84 static libxmlSAXDriver *activeDriver = nil;
85
86 static void
87 _startElement(libxmlSAXDriver *self, const xmlChar *name, const xmlChar **atts);
88 static void _endElement(libxmlSAXDriver *self, const xmlChar *name);
89 static void _startDocument(libxmlSAXDriver *self);
90 static void _endDocument(libxmlSAXDriver *self);
91 static void _characters(libxmlSAXDriver *self, const xmlChar *chars, int len);
92 static void
93 _ignorableWhiteSpace(libxmlSAXDriver *self, const xmlChar *chars, int len);
94 static void __pi(libxmlSAXDriver *self, const xmlChar *target, const xmlChar *data);
95 static void _comment(libxmlSAXDriver *self, const xmlChar *value);
96 static xmlParserInputPtr
97 _resolveEntity(libxmlSAXDriver *self, const xmlChar *pub, const xmlChar *sys)
98      __attribute__((unused));
99 static xmlEntityPtr _getEntity(libxmlSAXDriver *self, const xmlChar *name)
100      __attribute__((unused));
101 static void _warning(libxmlSAXDriver *self, const char *msg, ...);
102 static void _error(libxmlSAXDriver *self, const char *msg, ...);
103 static void _fatalError(libxmlSAXDriver *self, const char *msg, ...);
104 static void _setLocator(void *udata, xmlSAXLocatorPtr _locator);
105 static void _cdataBlock(libxmlSAXDriver *self, const xmlChar *value, int len);
106 static void _entityDecl(libxmlSAXDriver *self, const xmlChar *name, int type,
107                        const xmlChar *publicId, const xmlChar *systemId,
108                        xmlChar *content)
109      __attribute__((unused));
110 static void _notationDecl(libxmlSAXDriver *self, const xmlChar *name,
111                          const xmlChar *publicId, const xmlChar *systemId)
112      __attribute__((unused));
113 static void
114 _unparsedEntityDecl(libxmlSAXDriver *self, const xmlChar *name,
115                    const xmlChar *publicId, const xmlChar *systemId,
116                    const xmlChar *notationName)
117      __attribute__((unused));
118 static void _elementDecl(libxmlSAXDriver *self, const xmlChar *name, int type,
119                         xmlElementContentPtr content)
120      __attribute__((unused));
121 static void _attrDecl(libxmlSAXDriver *self, const xmlChar *elem,
122                      const xmlChar *name, int type, int def,
123                      const xmlChar *defaultValue, xmlEnumerationPtr tree)
124      __attribute__((unused));
125 static void _internalSubset(libxmlSAXDriver *ctx, const xmlChar *name,
126                            const xmlChar *ExternalID, const xmlChar *SystemID);
127 static void _externalSubset(libxmlSAXDriver *ctx, const xmlChar *name,
128                            const xmlChar *ExternalID, const xmlChar *SystemID);
129 static void _reference(libxmlSAXDriver *ctx, const xmlChar *name);
130 #if 0
131 static int _isStandalone(libxmlSAXDriver *self);
132 static int _hasInternalSubset(libxmlSAXDriver *self);
133 static int _hasExternalSubset(libxmlSAXDriver *self);
134 #endif
135
136 static xmlSAXHandler saxHandler = {
137   (void*)_internalSubset,      /* internalSubset */
138 #if 1
139   NULL,NULL,NULL,
140 #else
141   (void*)_isStandalone,        /* isStandalone */
142   (void*)_hasInternalSubset,   /* hasInternalSubset */
143   (void*)_hasExternalSubset,   /* hasExternalSubset */
144 #endif
145 #if HANDLE_XML_ENTITIES
146   (void*)_resolveEntity,       /* resolveEntity */
147   (void*)_getEntity,           /* getEntity */
148 #else
149   NULL, NULL,
150 #endif
151 #if HANDLE_XML_DELCS
152   (void*)_entityDecl,          /* entityDecl */
153   (void*)_notationDecl,        /* notationDecl */
154   (void*)_attrDecl,            /* attributeDecl */
155   (void*)_elementDecl,         /* elementDecl */
156   (void*)_unparsedEntityDecl,  /* unparsedEntityDecl */
157 #else
158   NULL, NULL, NULL, NULL, NULL,
159 #endif
160   (void*)_setLocator,          /* setDocumentLocator */
161   (void*)_startDocument,       /* startDocument */
162   (void*)_endDocument,         /* endDocument */
163   (void*)_startElement,        /* startElement */
164   (void*)_endElement,          /* endElement */
165   (void*)_reference,           /* reference */
166   (void*)_characters,          /* characters */
167   (void*)_ignorableWhiteSpace, /* ignorableWhitespace */
168   (void*)__pi,                  /* processingInstruction */
169   (void*)_comment,             /* comment */
170   (void*)_warning,             /* warning */
171   (void*)_error,               /* error */
172   (void*)_fatalError,          /* fatalError */
173   NULL,       /* getParameterEntity */
174   (void*)_cdataBlock,          /* cdataBlock */
175   (void*)_externalSubset       /* externalSubset */
176 };
177
178 - (id)init {
179   self->sax     = &saxHandler;
180   self->nsStack = [[NSMutableArray alloc] init];
181   
182   /* feature defaults */
183   self->fNamespaces        = YES;
184   self->fNamespacePrefixes = NO;
185   
186   return self;
187 }
188
189 - (void)dealloc {
190   [self->attrs   release];
191   [self->nsStack release];
192   
193   [self->declHandler    release];
194   [self->lexicalHandler release];
195   [self->contentHandler release];
196   [self->dtdHandler     release];
197   [self->errorHandler   release];
198   [self->entityResolver release];
199   
200   [self->locator clear];
201   [self->locator release];
202
203   if (self->entity) free(self->entity);
204   [super dealloc];
205 }
206
207 /* properties */
208
209 - (void)setProperty:(NSString *)_name to:(id)_value {
210   if ([_name isEqualToString:SaxLexicalHandlerProperty]) {
211     ASSIGN(self->lexicalHandler, _value);
212     return;
213   }
214   if ([_name isEqualToString:SaxDeclHandlerProperty]) {
215     ASSIGN(self->declHandler, _value);
216     return;
217   }
218   
219   [SaxNotRecognizedException raise:@"PropertyException"
220                              format:@"don't know property %@", _name];
221 }
222 - (id)property:(NSString *)_name {
223   if ([_name isEqualToString:SaxLexicalHandlerProperty])
224     return self->lexicalHandler;
225   if ([_name isEqualToString:SaxDeclHandlerProperty])
226     return self->declHandler;
227   
228   [SaxNotRecognizedException raise:@"PropertyException"
229                              format:@"don't know property %@", _name];
230   return nil;
231 }
232
233 /* features */
234
235 - (void)setFeature:(NSString *)_name to:(BOOL)_value {
236   if ([_name isEqualToString:@"http://xml.org/sax/features/namespaces"]) {
237     self->fNamespaces = _value;
238     return;
239   }
240   
241   if ([_name isEqualToString:
242                @"http://xml.org/sax/features/namespace-prefixes"]) {
243     self->fNamespacePrefixes = _value;
244     return;
245   }
246
247   [SaxNotRecognizedException raise:@"FeatureException"
248                              format:@"don't know feature %@", _name];
249 }
250 - (BOOL)feature:(NSString *)_name {
251   if ([_name isEqualToString:@"http://xml.org/sax/features/namespaces"])
252     return self->fNamespaces;
253   
254   if ([_name isEqualToString:
255                @"http://xml.org/sax/features/namespace-prefixes"])
256     return self->fNamespacePrefixes;
257   
258   if ([_name isEqualToString:
259                @"http://www.skyrix.com/sax/features/predefined-namespaces"])
260     return YES;
261   
262   [SaxNotRecognizedException raise:@"FeatureException"
263                              format:@"don't know feature %@", _name];
264   return NO;
265 }
266
267 /* handlers */
268
269 - (void)setDTDHandler:(id<NSObject,SaxDTDHandler>)_handler {
270   ASSIGN(self->dtdHandler, _handler);
271 }
272 - (id<NSObject,SaxDTDHandler>)dtdHandler {
273   return self->dtdHandler;
274 }
275
276 - (void)setErrorHandler:(id<NSObject,SaxErrorHandler>)_handler {
277   ASSIGN(self->errorHandler, _handler);
278 }
279 - (id<NSObject,SaxErrorHandler>)errorHandler {
280   return self->errorHandler;
281 }
282
283 - (void)setEntityResolver:(id<NSObject,SaxEntityResolver>)_handler {
284   ASSIGN(self->entityResolver, _handler);
285 }
286 - (id<NSObject,SaxEntityResolver>)entityResolver {
287   return self->entityResolver;
288 }
289
290 - (void)setContentHandler:(id<NSObject,SaxContentHandler>)_handler {
291   ASSIGN(self->contentHandler, _handler);
292 }
293 - (id<NSObject,SaxContentHandler>)contentHandler {
294   return self->contentHandler;
295 }
296
297 /* parsing */
298
299 - (NSStringEncoding)encodingForXMLEncodingString:(NSString *)_enc {
300   // TODO: use the string-charset functions in NGExtensions
301   _enc = [_enc lowercaseString];
302
303   if ([_enc isEqualToString:@"utf-8"])
304     return NSUTF8StringEncoding;
305   if ([_enc isEqualToString:@"iso-8859-1"])
306     return NSISOLatin1StringEncoding;
307   
308 #ifndef NeXT_Foundation_LIBRARY
309   if ([_enc isEqualToString:@"iso-8859-9"])
310     return NSISOLatin9StringEncoding;
311 #endif
312
313   if ([_enc isEqualToString:@"iso-8859-2"])
314     return NSISOLatin2StringEncoding;
315
316   if ([_enc isEqualToString:@"ascii"])
317     return NSASCIIStringEncoding;
318
319   NSLog(@"%s: UNKNOWN XML ENCODING '%@'",
320         __PRETTY_FUNCTION__, _enc);
321   return 0;
322 }
323 - (NSData *)dataForXMLString:(NSString *)_string {
324   NSData  *data;
325   NSRange r;
326
327   data = nil;
328   
329   r = [_string rangeOfString:@"?>"];
330   if ([_string hasPrefix:@"<?xml "] && (r.length != 0)) {
331     NSString *xmlDecl;
332     
333     xmlDecl = [_string substringToIndex:r.location];
334     
335     r = [xmlDecl rangeOfString:@"encoding='"];
336     if (r.length > 0) {
337       xmlDecl = [_string substringFromIndex:(r.location + 10)];
338       r = [xmlDecl rangeOfString:@"'"];
339       xmlDecl = (r.length > 0)
340         ? [xmlDecl substringToIndex:r.location]
341         : nil;
342     }
343     else {
344       r = [xmlDecl rangeOfString:@"encoding=\""];
345       if (r.length > 0) {
346         xmlDecl = [_string substringFromIndex:(r.location + r.length)];
347         r = [xmlDecl rangeOfString:@"\""];
348         xmlDecl = r.length > 0
349           ? [xmlDecl substringToIndex:r.location]
350           : nil;
351       }
352       else
353         xmlDecl = nil;
354     }
355     
356     if ([xmlDecl length] > 0) {
357       NSStringEncoding enc;
358         
359       if ((enc = [self encodingForXMLEncodingString:xmlDecl]) != 0) {
360         data = [_string dataUsingEncoding:enc];
361         if (data == nil) {
362           NSLog(@"WARNING(%s): couldn't get data for string '%@', "
363                 @"encoding %i !", __PRETTY_FUNCTION__, _string, enc);
364           return nil;
365         }
366       }
367     }
368   }
369   
370   if (data == nil)
371     data = [_string dataUsingEncoding:NSUTF8StringEncoding];
372
373   return data;
374 }
375
376 - (void)parseFromSource:(id)_source systemId:(NSString *)_sysId {
377   NSAutoreleasePool *pool;
378   
379   if (_source == nil) {
380     /* no source ??? */
381     return;
382   }
383   
384   if ([_source isKindOfClass:[NSString class]]) {
385     /* convert strings to UTF8 data */
386     if (_sysId == nil) _sysId = @"<string>";
387     _source = [self dataForXMLString:_source];
388   }
389   else if ([_source isKindOfClass:[NSURL class]]) {
390     if (_sysId == nil) _sysId = [_source absoluteString];
391     _source = [_source resourceDataUsingCache:NO];
392   }
393   else if ([_source isKindOfClass:[NSData class]]) {
394     if (_sysId == nil) _sysId = @"<data>";
395   }
396   else {
397     SaxParseException *e;
398     NSDictionary      *ui;
399     
400     ui = [NSDictionary dictionaryWithObjectsAndKeys:
401                          _source ? _source : @"<nil>", @"source",
402                          self,                         @"parser",
403                          nil];
404     
405     e = (id)[SaxParseException exceptionWithName:@"SaxIOException"
406                                reason:@"can't handle data-source"
407                                userInfo:ui];
408     
409     [self->errorHandler fatalError:e];
410     return;
411   }
412   
413   pool = [[NSAutoreleasePool alloc] init];
414
415   /* start parsing */
416   {
417     unsigned char *src, *start;
418     unsigned len;
419     void     *oldsax;
420     
421     if ((len = [_source length]) == 0) {
422       /* no content ... */
423       return;
424     }
425     
426     /* zero-terminate the data !!! */
427     src = malloc(len + 1);
428     [_source getBytes:src length:len];
429     src[len] = '\0';
430     start = src;
431     
432     if (len > 5) {
433       unsigned char *tmp;
434       
435       if ((tmp = strstr(src, "<?xml"))) {
436         if (tmp != src) {
437           /* skip leading spaces till <?xml ...*/
438           while (*start != '\0' && isspace(*start)) {
439             start++;
440             len--;
441           }
442         }
443       }
444     }
445     
446     if (activeDriver != nil) {
447       NSLog(@"ERROR(%s): %@ there is an active driver set (%@), override !",
448             __PRETTY_FUNCTION__, self, activeDriver);
449     }
450     activeDriver = self;
451     
452     self->ctxt =
453       xmlCreateMemoryParserCtxt(start, len);
454     
455     if (self->ctxt == nil) {
456       SaxParseException *e;
457       NSDictionary *ui;
458       
459       NSLog(@"%s: couldn't create memory parser ctx (src=0x%08X, len=%d) !",
460             __PRETTY_FUNCTION__, src, len);
461       
462       if (activeDriver == self)
463         activeDriver = nil;
464       
465       ui = nil;
466       e = (id)[SaxParseException exceptionWithName:@"SaxIOException"
467                                  reason:@"couldn't create memory parser context"
468                                  userInfo:ui];
469       
470       [self->errorHandler fatalError:e];
471       return;
472     }
473     
474     if (((xmlParserCtxtPtr)self->ctxt)->input != NULL && [_sysId length] > 0) {
475       ((xmlParserInputPtr)((xmlParserCtxtPtr)self->ctxt)->input)->filename =
476         [_sysId cString];
477     }
478     
479     oldsax = ((xmlParserCtxtPtr)self->ctxt)->sax;
480     ((xmlParserCtxtPtr)self->ctxt)->sax = self->sax;
481     ((xmlParserCtxtPtr)self->ctxt)->userData = self;
482     
483     xmlParseDocument(ctxt);
484     
485     if (!(((xmlParserCtxtPtr)self->ctxt)->wellFormed))
486       NSLog(@"%@: not well formed", _sysId);
487     
488     if (((xmlParserCtxtPtr)self->ctxt)->input != NULL && [_sysId length] > 0)
489       ((xmlParserInputPtr)((xmlParserCtxtPtr)self->ctxt)->input)->filename =NULL;
490     
491     ((xmlParserCtxtPtr)self->ctxt)->sax = oldsax;
492     ((xmlParserCtxtPtr)self->ctxt)->userData = NULL;
493     xmlFreeParserCtxt(ctxt);
494     
495     if (activeDriver == self)
496       activeDriver = nil;
497     
498     if (src) { 
499       free(src); 
500       src = NULL;
501     }
502   }
503   
504   [pool release];
505 }
506 - (void)parseFromSource:(id)_source {
507   [self parseFromSource:_source systemId:nil];
508 }
509
510 static int mfread(void *f, char *buf, int len) {
511   int l;
512   l = fread(buf, 1, len, f);
513   //printf("read %i bytes\n", l);
514   return l;
515 }
516 static int mfclose(void *f) {
517   return fclose(f);
518 }
519
520 - (void)parseFromSystemId:(NSString *)_sysId {
521   /* _sysId is a URI */
522   NSAutoreleasePool *pool;
523   
524   if (![_sysId hasPrefix:@"file:"]) {
525     SaxParseException *e;
526     NSDictionary      *ui;
527     NSURL *url;
528     
529     if ((url = [NSURL URLWithString:_sysId])) {
530       [self parseFromSource:url systemId:_sysId];
531       return;
532     }
533     
534     ui = [NSDictionary dictionaryWithObjectsAndKeys:
535                          _sysId ? _sysId : @"<nil>", @"systemID",
536                          self,                       @"parser",
537                          nil];
538     
539     e = (id)[SaxParseException exceptionWithName:@"SaxIOException"
540                                reason:@"can't handle system-id"
541                                userInfo:ui];
542     
543     [self->errorHandler fatalError:e];
544     return;
545   }
546   
547   pool = [[NSAutoreleasePool alloc] init];
548   
549   /* cut off file:// */
550   if ([_sysId hasPrefix:@"file://"])
551     _sysId = [_sysId substringFromIndex:7];
552   else
553     _sysId = [_sysId substringFromIndex:5];
554   
555   /* start parsing .. */
556 #if 0
557   ret = xmlSAXUserParseFile(self->sax, (void *)self, [_sysId cString]);
558 #else
559   {
560     FILE *f;
561     f = fopen([_sysId cString], "r");
562
563     if (f == NULL) {
564       SaxParseException *e;
565       NSDictionary *ui;
566 #if DEBUG
567       NSLog(@"%s: missing file '%@'", __PRETTY_FUNCTION__, _sysId);
568 #endif
569       ui = [NSDictionary dictionaryWithObjectsAndKeys:
570                            _sysId ? _sysId : @"<nil>", @"path",
571                            self,                       @"parser",
572                            nil];
573       e = (id)[SaxParseException exceptionWithName:@"SaxIOException"
574                                  reason:@"can't find file"
575                                  userInfo:ui];
576       
577       [self->errorHandler fatalError:e];
578       [pool release];
579       return;
580     }
581     
582     self->ctxt =
583       xmlCreateIOParserCtxt(self->sax, self /* userdata */,
584                             mfread,  /* ioread  */
585                             mfclose, /* ioclose */
586                             f,       /* ioctx   */
587                             XML_CHAR_ENCODING_UTF8 /* encoding */);
588     
589     if (((xmlParserCtxtPtr)self->ctxt)->input != NULL && [_sysId length] > 0) {
590       ((xmlParserInputPtr)((xmlParserCtxtPtr)self->ctxt)->input)->filename =
591         [_sysId cString];
592     }
593     
594     if (activeDriver != nil) {
595       NSLog(@"WARNING(%s): %@ there is an active driver set (%@), override !",
596             __PRETTY_FUNCTION__, self, activeDriver);
597     }
598     activeDriver = self;
599     
600     xmlParseDocument(self->ctxt);
601     
602     if (activeDriver == self)
603       activeDriver = nil;
604     
605     if (((xmlParserCtxtPtr)self->ctxt)->input != NULL && [_sysId length] > 0)
606       ((xmlParserInputPtr)((xmlParserCtxtPtr)self->ctxt)->input)->filename =NULL;
607     
608     if (!(((xmlParserCtxtPtr)self->ctxt)->wellFormed))
609       NSLog(@"%@: not well formed", _sysId);
610     
611     ((xmlParserCtxtPtr)self->ctxt)->sax = NULL;
612     xmlFreeParserCtxt(self->ctxt);
613   }
614 #endif
615
616   [pool release];
617 }
618
619 /* entities */
620
621 - (NSString *)replacementStringForEntityNamed:(NSString *)_entityName {
622   // TODO: check, how this is used, could explain some problems
623   //NSLog(@"get entity: %@", _entityName);
624   return [[@"&amp;" stringByAppendingString:_entityName]
625                     stringByAppendingString:@";"];
626 }
627
628 /* namespace support */
629
630 - (NSString *)nsUriForPrefix:(NSString *)_prefix {
631   NSEnumerator *e;
632   NSDictionary *ns;
633   
634   e = [self->nsStack reverseObjectEnumerator];
635   while ((ns = [e nextObject])) {
636     NSString *uri;
637     
638     if ((uri = [ns objectForKey:_prefix])) {
639       //NSLog(@"prefix %@ -> uri %@", _prefix, uri);
640       return uri;
641     }
642   }
643   //NSLog(@"prefix %@ -> uri %@", _prefix, nil);
644   return nil;
645 }
646
647 - (NSString *)defaultNamespace {
648   return [self nsUriForPrefix:@":"];
649 }
650
651 - (void)declarePrefix:(NSString *)_prefix namespaceURI:(NSString *)_uri {
652   NSMutableDictionary *ns = nil;
653   NSDictionary *newns;
654   unsigned count;
655   
656   NSCAssert(self->nsStack, @"missing namespace stack");
657
658   if ((count = [self->nsStack count]) == 0)
659     ns = [[NSMutableDictionary alloc] initWithCapacity:2];
660   else
661     ns = [[self->nsStack lastObject] mutableCopy];
662   
663   if ([_prefix length] == 0)
664     _prefix = @":";
665   
666   [ns setObject:_uri forKey:_prefix];
667
668   newns = [ns copy];
669   [ns release];
670
671   if (count == 0)
672     [self->nsStack addObject:newns];
673   else
674     [self->nsStack replaceObjectAtIndex:(count - 1) withObject:newns];
675   
676   [newns release];
677 }
678
679 /* ---------- libxml sax connection ---------- */
680
681 static void
682 _startElement(libxmlSAXDriver *self, const xmlChar *name, const xmlChar **atts)
683 {
684   NSString *ename, *rawName, *euri;
685   NSDictionary *nsDict = nil;
686   NSRange r;
687   
688   /* first scan for namespace declaration */
689   
690   if (atts) {
691     NSMutableDictionary *ns = nil;
692     int i;
693     
694     for (i = 0; atts[i]; i += 2) {
695       const xmlChar *an = atts[i];
696       
697       /* check for attr-names beginning with 'xmlns' */
698       if (an[0] != 'x') continue;
699       if (an[1] != 'm') continue;
700       if (an[2] != 'l') continue;
701       if (an[3] != 'n') continue;
702       if (an[4] != 's') continue;
703       
704       /* ok, found ns decl */
705       
706       if (ns == nil) ns = [[NSMutableDictionary alloc] init];
707       
708       if (an[5] == ':') {
709         /* eg <x xmlns:nl="http://www.w3.org"/> */
710         NSString *prefix, *uri;
711         
712         if (an[6] == '\0') {
713           /* invalid, namespace name may not be empty ! */
714           NSLog(@"WARNING(%s): empty namespace prefix !", __PRETTY_FUNCTION__);
715         }
716         
717         prefix = xmlCharsToString(&(an[6]));
718         uri    = xmlCharsToString(atts[i + 1]);
719         
720         //NSLog(@"prefix %@ uri %@", prefix, uri);
721         
722         NSCAssert(ns, @"missing namespace dictionary");
723         [ns setObject:uri forKey:prefix];
724         
725         if (self->fNamespaces)
726           [self->contentHandler startPrefixMapping:prefix uri:uri];
727
728         [prefix release]; prefix = nil;
729         [uri release];    uri    = nil;
730       }
731       else {
732         /* eg <x xmlns="http://www.w3.org"/> */
733         NSString *uri;
734         
735         uri = xmlCharsToString(atts[i + 1]);
736         [ns setObject:uri forKey:@":"];
737
738         //NSLog(@"prefix default uri %@", uri);
739         [uri release]; uri = nil;
740       }
741     }
742     
743     nsDict = [ns copy];
744     [ns release];
745   }
746   
747   /* manage namespace stack */
748   
749   if (nsDict == nil)
750     nsDict = [NSDictionary dictionary];
751   
752   NSCAssert(self->nsStack, @"missing namespace stack");
753   [self->nsStack addObject:nsDict];
754   
755   /* process element name */
756   
757   rawName = xmlCharsToString(name);
758   r = [rawName rangeOfString:@":"];
759   if (r.length > 0) {
760     /* eg: <edi:bill/> */
761     NSString *prefix;
762     
763     prefix = [rawName substringToIndex:r.location];
764     ename  = [rawName substringFromIndex:(r.location + r.length)];
765     euri   = [self nsUriForPrefix:prefix];
766   }
767   else {
768     ename = rawName;
769     euri  = [self defaultNamespace];
770   }
771   
772   /* create sax attrs */
773
774   if (self->attrs == nil)
775     self->attrs = [[SaxAttributes alloc] init];
776   else
777     [self->attrs clear];
778   
779   if (atts) {
780     int i;
781     
782     for (i = 0; atts[i]; i += 2) {
783       NSString *name, *rawName, *uri;
784       NSString *type, *value;
785       NSRange  r;
786
787       if (!self->fNamespacePrefixes) {
788         if (atts[i][0] == 'x') {
789           const char *an = atts[i];
790         
791           if (strstr(an, "xmlns") == an)
792             continue;
793         }
794       }
795       
796       rawName = xmlCharsToString(atts[i]);
797       r = [rawName rangeOfString:@":"];
798       
799       if (r.length > 0) {
800         /* explicit attribute namespace, eg '<d edi:bill="100"/>' */
801         NSString *prefix;
802         
803         prefix = [rawName substringToIndex:r.location];
804         name   = [rawName substringFromIndex:(r.location + r.length)];
805         uri    = [self nsUriForPrefix:prefix];
806       }
807       else {
808         /* plain attribute, eg '<d bill="100"/>' */
809         name   = rawName;
810         uri    = euri; /* attr inherits namespace from element-name */
811       }
812       
813       type  = @"CDATA";
814       value = xmlCharsToString(atts[i + 1]);
815       
816       [self->attrs
817            addAttribute:name uri:uri rawName:rawName
818            type:type value:value];
819
820       [value   release]; value   = nil;
821       [rawName release]; rawName = nil;
822     }
823   }
824   
825   self->depth++;
826   
827   /* send notification */
828   
829   [self->contentHandler startElement:ename namespace:euri
830                         rawName:rawName
831                         attributes:self->attrs];
832
833   [rawName release]; rawName = nil;
834   
835   [self->attrs clear];
836 }
837
838 static void _endElement(libxmlSAXDriver *self, const xmlChar *name) {
839   NSString *ename, *rawName, *uri;
840   NSRange  r;
841   
842   rawName = xmlCharsToString(name);
843   r = [rawName rangeOfString:@":"];
844   
845   if (r.length > 0) {
846     /* eg: <edi:bill/> */
847     NSString *prefix;
848     
849     prefix = [rawName substringToIndex:r.location];
850     ename  = [rawName substringFromIndex:(r.location + r.length)];
851     uri    = [self nsUriForPrefix:prefix];
852   }
853   else {
854     ename = rawName;
855     uri   = [self defaultNamespace];
856   }
857   
858   [self->contentHandler endElement:ename namespace:uri rawName:rawName];
859   self->depth--;
860   [rawName release]; rawName = nil;
861
862   /* process namespace stack */
863
864   if (self->fNamespaces) {
865     NSDictionary *ns;
866     NSEnumerator *keys;
867     NSString     *key;
868     
869     ns = [self->nsStack lastObject];
870     keys = [ns keyEnumerator];
871     while ((key = [keys nextObject])) {
872       if ([key isEqualToString:@":"])
873         continue;
874       [self->contentHandler endPrefixMapping:key];
875     }
876   }
877   [self->nsStack removeLastObject];
878 }
879
880 static void _startDocument(libxmlSAXDriver *self) {
881   static NSDictionary *defNS = nil;
882   id keys[2], values[2];
883
884   //NSLog(@"start doc 0x%08X", self);
885
886   if (defNS == nil) {
887     keys[0] = @"xml"; values[0] = @"http://www.w3.org/XML/1998/namespace";
888     keys[1] = @":";   values[1] = @"";
889     defNS = [[NSDictionary alloc] initWithObjects:values forKeys:keys count:2];
890   }
891   if ([self->nsStack count] == 0)
892     [self->nsStack addObject:defNS];
893   else
894     [self->nsStack insertObject:defNS atIndex:0];
895   
896   [self->contentHandler startDocument];
897 }
898 static void _endDocument(libxmlSAXDriver *self) {
899   [self->contentHandler endDocument];
900   
901   if ([self->nsStack count] > 0)
902     [self->nsStack removeObjectAtIndex:0];
903   else {
904     NSLog(@"libxmlSAXDriver: inconsistent state, "
905           @"nothing on NS stack in endDocument !");
906   }
907 }
908
909 static void _characters(libxmlSAXDriver *self, const xmlChar *chars, int len) {
910   /* need to transform UTF8 to UTF16 */
911   unichar *data, *ts;
912   
913   if (len == 0) {
914     unichar c = 0;
915     data = &c;
916     [self->contentHandler characters:data length:0];
917     return;
918   }
919   if (chars == NULL) {
920     [self->contentHandler characters:NULL length:0];
921     return;
922   }
923   
924   data = ts = calloc(len + 1, sizeof(unichar)); /* GC ?! */
925   
926   if (_UTF8ToUTF16((void *)&chars, (void *)(chars + len),
927                    (void *)&ts, ts + (len * sizeof(unichar)))) {
928     free(data);
929     NSLog(@"ERROR(%s:%i): couldn't convert UTF8 to UTF16 !",
930           __PRETTY_FUNCTION__, __LINE__);
931   }
932   else {
933     [self->contentHandler characters:data length:((unsigned)(ts - data))];
934     free(data);
935   }
936 }
937
938 static void
939 _ignorableWhiteSpace(libxmlSAXDriver *self, const xmlChar *chars, int len)
940 {
941   /* need to transform UTF8 to UTF16 */
942   unichar *data, *ts;
943   
944   if (len == 0) {
945     unichar c = 0;
946     data = &c;
947     [self->contentHandler ignorableWhitespace:data length:len];
948     return;
949   }
950   if (chars == NULL) {
951     [self->contentHandler ignorableWhitespace:NULL length:0];
952     return;
953   }
954   
955   data = ts = calloc(len + 1, sizeof(unichar)); /* GC ?! */
956   
957   if (_UTF8ToUTF16((void *)&chars, (void *)(chars + len),
958                    (void *)&ts, ts + (len * sizeof(unichar)))) {
959     free(data);
960     NSLog(@"ERROR(%s:%i): couldn't convert UTF8 to UTF16 !",
961           __PRETTY_FUNCTION__, __LINE__);
962   }
963   else {
964     [self->contentHandler ignorableWhitespace:data length:(ts - data)];
965     free(data);
966   }
967 }
968
969 static void __pi(libxmlSAXDriver *self, const xmlChar *pi, const xmlChar *data) {
970   NSString *epi, *edata;
971   
972   epi   = xmlCharsToString(pi);
973   edata = xmlCharsToString(data);
974   
975   [self->contentHandler processingInstruction:epi data:edata];
976
977   [epi   release]; epi   = nil;
978   [edata release]; edata = nil;
979 }
980
981 static void _comment(libxmlSAXDriver *self, const xmlChar *value) {
982   if (self->lexicalHandler) {
983     /* need to transform UTF8 to UTF16 */
984     unichar *data;
985     register int i, len;
986     
987     len = strlen(value);
988     
989     data = calloc(len +1 ,sizeof(unichar)); /* GC ?! */
990
991     for (i = 0; i < len; i++)
992       data[i] = value[i];
993
994     [self->lexicalHandler comment:data length:len];
995     
996     if (data) { free(data); data = NULL; }
997   }
998 }
999
1000 static void _setLocator(void *udata, xmlSAXLocatorPtr _locator) {
1001   if (activeDriver == nil) { 
1002     NSLog(@"ERROR(%s): no driver is active !", __PRETTY_FUNCTION__);
1003     return;
1004   }
1005   
1006   [activeDriver->locator release];
1007   
1008   activeDriver->locator = [[libxmlSAXLocator alloc]
1009                                              initWithSaxLocator:_locator
1010                                              parser:activeDriver];
1011   activeDriver->locator->ctx = activeDriver->ctxt;
1012   
1013   [activeDriver->contentHandler setDocumentLocator:activeDriver->locator];
1014 }
1015
1016 static xmlParserInputPtr
1017 _resolveEntity(libxmlSAXDriver *self, const xmlChar *pub, const xmlChar *sys)
1018 {
1019   NSString *pubId, *sysId;
1020   id src;
1021
1022   pubId = xmlCharsToString(pub);
1023   sysId = xmlCharsToString(sys);
1024   
1025   src = [self->entityResolver resolveEntityWithPublicId:pubId systemId:sysId];
1026   if (src == nil) {
1027     //return xmlLoadExternalEntity(sys, pub, self);
1028     return NULL;
1029   }
1030   
1031   NSLog(@"ignored entity src %@", src);
1032   
1033   [pubId release]; pubId = nil;
1034   [sysId release]; sysId = nil;
1035   return NULL;
1036 }
1037
1038 static xmlEntityPtr _getEntity(libxmlSAXDriver *self, const xmlChar *name) {
1039   xmlEntityPtr p;
1040   NSString *ename, *s;
1041   
1042   if ((p = xmlGetPredefinedEntity(name)))
1043     return p;
1044   
1045   if (self->entity == NULL)
1046     /* setup shared entity structure */
1047     self->entity = calloc(1, sizeof(xmlEntity));
1048   
1049   ename = xmlCharsToString(name);
1050   s     = [self replacementStringForEntityNamed:ename];
1051
1052   /* need to convert to unicode ! */
1053   
1054   /* fill entity structure */
1055   p = self->entity;
1056   p->name    = [ename cString];
1057   p->etype   = XML_INTERNAL_GENERAL_ENTITY;
1058   p->orig    = (void *)[ename cString];
1059   p->content = (void *)[s cString];
1060   p->length  = [s cStringLength];
1061   
1062   [ename release]; ename = nil;
1063   
1064   return p;
1065 }
1066
1067 static void _cdataBlock(libxmlSAXDriver *self, const xmlChar *value, int len) {
1068   [self->lexicalHandler startCDATA];
1069   _characters(self, value, len);
1070   [self->lexicalHandler endCDATA];
1071 }
1072
1073 static SaxParseException *
1074 mkException(libxmlSAXDriver *self, NSString *key, const char *msg, va_list va)
1075 {
1076   NSString          *s, *reason;
1077   NSDictionary      *ui;
1078   SaxParseException *e;
1079   NSRange r;
1080   int count = 0, i;
1081   id  keys[7], values[7];
1082   id  tmp;
1083   
1084   s = [NSString stringWithCString:msg];
1085   s = [[[NSString alloc]
1086                   initWithFormat:s arguments:va]
1087                   autorelease];
1088   r = [s rangeOfString:@"\n"];
1089   reason = r.length > 0
1090     ? [s substringToIndex:r.location]
1091     : s;
1092   
1093   if ([reason length] == 0)
1094     reason = @"unknown reason";
1095   
1096   keys[0] = @"parser"; values[0] = self; count++;
1097   keys[1] = @"depth";  values[1] = [NSNumber numberWithInt:self->depth]; count++;
1098   
1099   if ([s length] > 0) {
1100     keys[count]   = @"errorMessage";
1101     values[count] = s;
1102     count++;
1103   }
1104   
1105   if ((i = [self->locator lineNumber]) >= 0) {
1106     keys[count] = @"line";
1107     values[count] = [NSNumber numberWithInt:i];
1108     count++;
1109   }
1110   if ((i = [self->locator columnNumber]) >= 0) {
1111     keys[count] = @"column";
1112     values[count] = [NSNumber numberWithInt:i];
1113     count++;
1114   }
1115   if ((tmp = [self->locator publicId])) {
1116     keys[count]   = @"publicId";
1117     values[count] = tmp;
1118     count++;
1119   }
1120   if ((tmp = [self->locator systemId])) {
1121     keys[count]   = @"systemId";
1122     values[count] = tmp;
1123     count++;
1124   }
1125   
1126   ui = [NSDictionary dictionaryWithObjects:values forKeys:keys count:count];
1127   
1128   e = (id)[SaxParseException exceptionWithName:key
1129                              reason:reason
1130                              userInfo:ui];
1131   return e;
1132 }
1133
1134 static void _warning(libxmlSAXDriver *self, const char *msg, ...) {
1135   va_list           args;
1136   SaxParseException *e;
1137
1138   va_start(args, msg);
1139   e = mkException(self, @"SAXWarning", msg, args);
1140   va_end(args);
1141   
1142   [self->errorHandler warning:e];
1143 }
1144 static void _error(libxmlSAXDriver *self, const char *msg, ...) {
1145   va_list           args;
1146   SaxParseException *e;
1147
1148   va_start(args, msg);
1149   e = mkException(self, @"SAXError", msg, args);
1150   va_end(args);
1151   
1152   [self->errorHandler error:e];
1153 }
1154 static void _fatalError(libxmlSAXDriver *self, const char *msg, ...) {
1155   va_list           args;
1156   SaxParseException *e;
1157
1158   va_start(args, msg);
1159   e = mkException(self, @"SAXFatalError", msg, args);
1160   va_end(args);
1161   
1162   [self->errorHandler fatalError:e];
1163 }
1164
1165 static void _entityDecl(libxmlSAXDriver *self, const xmlChar *name, int type,
1166                        const xmlChar *publicId, const xmlChar *systemId,
1167                        xmlChar *content)
1168 {
1169   NSString *ename, *pubId, *sysId;
1170   NSString *value;
1171   
1172   ename = xmlCharsToString(name);
1173   pubId = xmlCharsToString(publicId);
1174   sysId = xmlCharsToString(systemId);
1175   value = xmlCharsToString(content);
1176   
1177   switch (type) {
1178     case XML_INTERNAL_GENERAL_ENTITY:
1179     case XML_INTERNAL_PARAMETER_ENTITY:
1180     case XML_INTERNAL_PREDEFINED_ENTITY:
1181       [self->declHandler internalEntityDeclaration:ename value:value];
1182       break;
1183     
1184     case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
1185     case XML_EXTERNAL_PARAMETER_ENTITY:
1186       [self->declHandler externalEntityDeclaration:ename
1187                          publicId:pubId systemId:sysId];
1188       break;
1189       
1190     case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
1191       /* is content really =notationName ??? */
1192       NSLog(@"unparsed ext entity ..");
1193       [self->dtdHandler unparsedEntityDeclaration:ename
1194                         publicId:pubId systemId:sysId
1195                         notationName:value];
1196       break;
1197       
1198     default:
1199       [NSException raise:@"InvalidEntityType"
1200                    format:@"don't know entity type with code %i", type];
1201   }
1202
1203   [ename release];
1204   [pubId release];
1205   [sysId release];
1206   [value release];
1207 }
1208
1209 static void
1210 _unparsedEntityDecl(libxmlSAXDriver *self,const xmlChar *name,
1211                     const xmlChar *publicId, const xmlChar *systemId,
1212                     const xmlChar *notationName)
1213 {
1214   if (self->dtdHandler) {
1215     NSString *ename, *nname, *pubId, *sysId;
1216     
1217     ename = xmlCharsToString(name);
1218     nname = xmlCharsToString(notationName);
1219     pubId = xmlCharsToString(publicId);
1220     sysId = xmlCharsToString(systemId);
1221     
1222     [self->dtdHandler unparsedEntityDeclaration:ename
1223                       publicId:pubId systemId:sysId
1224                       notationName:nname];
1225
1226     [ename release];
1227     [nname release];
1228     [pubId release];
1229     [sysId release];
1230   }
1231 }
1232
1233 static void _notationDecl(libxmlSAXDriver *self, const xmlChar *name,
1234                          const xmlChar *publicId, const xmlChar *systemId)
1235 {
1236   if (self->dtdHandler) {
1237     NSString *nname, *pubId, *sysId;
1238     
1239     nname = xmlCharsToString(name);
1240     pubId = xmlCharsToString(publicId);
1241     sysId = xmlCharsToString(systemId);
1242     
1243     [self->dtdHandler notationDeclaration:nname publicId:pubId systemId:sysId];
1244
1245     [nname release];
1246     [pubId release];
1247     [sysId release];
1248   }
1249 }
1250
1251 static NSString *_occurString(xmlElementContentOccur _occurType)
1252      __attribute__((unused));
1253 static NSString *_occurString(xmlElementContentOccur _occurType) {
1254   switch (_occurType) {
1255     case XML_ELEMENT_CONTENT_ONCE: return @"";
1256     case XML_ELEMENT_CONTENT_OPT:  return @"?";
1257     case XML_ELEMENT_CONTENT_MULT: return @"*";
1258     case XML_ELEMENT_CONTENT_PLUS: return @"+";
1259   }
1260   return @"";
1261 }
1262
1263 static void _addElemModel(xmlElementContentPtr p, NSMutableString *s, int pt) {
1264   if (p == NULL) return;
1265
1266   switch (p->type) {
1267     case XML_ELEMENT_CONTENT_PCDATA:
1268       if (pt == -1) [s appendString:@"("];
1269       [s appendString:@"#PCDATA"];
1270       if (pt == -1) [s appendString:@")"];
1271       break;
1272       
1273     case XML_ELEMENT_CONTENT_ELEMENT: {
1274       NSString *ename;
1275       
1276       ename = xmlCharsToString(p->name);
1277       
1278       if (pt == -1) [s appendString:@"("];
1279       [s appendString:ename];
1280       if (pt == -1) [s appendString:@")"];
1281
1282       [ename release]; ename = nil;
1283       break;
1284     }
1285     
1286     case XML_ELEMENT_CONTENT_SEQ:
1287       if (pt != XML_ELEMENT_CONTENT_SEQ) [s appendString:@"("];
1288       _addElemModel(p->c1, s, XML_ELEMENT_CONTENT_SEQ);
1289       [s appendString:@","];
1290       _addElemModel(p->c2, s, XML_ELEMENT_CONTENT_SEQ);
1291       if (pt != XML_ELEMENT_CONTENT_SEQ) [s appendString:@")"];
1292       break;
1293       
1294     case XML_ELEMENT_CONTENT_OR:
1295       if (pt != XML_ELEMENT_CONTENT_OR) [s appendString:@"("];
1296       _addElemModel(p->c1, s, XML_ELEMENT_CONTENT_OR);
1297       [s appendString:@"|"];
1298       _addElemModel(p->c2, s, XML_ELEMENT_CONTENT_OR);
1299       if (pt != XML_ELEMENT_CONTENT_OR) [s appendString:@")"];
1300       break;
1301   }
1302   switch (p->ocur) {
1303     case XML_ELEMENT_CONTENT_ONCE: break;
1304     case XML_ELEMENT_CONTENT_OPT:  [s appendString:@"?"]; break;
1305     case XML_ELEMENT_CONTENT_MULT: [s appendString:@"*"]; break;
1306     case XML_ELEMENT_CONTENT_PLUS: [s appendString:@"+"]; break;
1307   }
1308 }
1309
1310 static void _elementDecl(libxmlSAXDriver *self, const xmlChar *name, int type,
1311                         xmlElementContentPtr content)
1312 {
1313   if (self->declHandler) {
1314     NSString *ename, *model;
1315     
1316     ename = xmlCharsToString(name);
1317     
1318     if (content) {
1319       NSMutableString *emodel;
1320       
1321       emodel = [[NSMutableString alloc] init];
1322       _addElemModel(content, emodel, -1);
1323       model = [[emodel copy] autorelease];
1324       [emodel release];
1325     }
1326     else
1327       model = nil;
1328     
1329     [self->declHandler elementDeclaration:ename contentModel:model];
1330     [ename release]; ename = nil;
1331   }
1332 }
1333
1334 static void _attrDecl(libxmlSAXDriver *self, const xmlChar *elem,
1335                      const xmlChar *name, int type, int def,
1336                      const xmlChar *defaultValue, xmlEnumerationPtr tree)
1337 {
1338   if (self->declHandler) {
1339     NSString *ename, *aname, *defValue, *atype, *defType;
1340     
1341     ename    = xmlCharsToString(elem);
1342     aname    = xmlCharsToString(name);
1343     defValue = xmlCharsToString(defaultValue);
1344     atype    = nil;
1345     defType  = nil;
1346
1347     switch (type) {
1348       case XML_ATTRIBUTE_CDATA:       atype = @"CDATA";       break;
1349       case XML_ATTRIBUTE_ID:          atype = @"ID";          break;
1350       case XML_ATTRIBUTE_IDREF:       atype = @"IDREF";       break;
1351       case XML_ATTRIBUTE_IDREFS:      atype = @"IDREFS";      break;
1352       case XML_ATTRIBUTE_ENTITY:      atype = @"ENTITY";      break;
1353       case XML_ATTRIBUTE_ENTITIES:    atype = @"ENTITIES";    break;
1354       case XML_ATTRIBUTE_NMTOKEN:     atype = @"NMTOKEN";     break;
1355       case XML_ATTRIBUTE_NMTOKENS:    atype = @"NMTOKENS";    break;
1356       case XML_ATTRIBUTE_ENUMERATION: atype = @"ENUMERATION"; break;
1357       case XML_ATTRIBUTE_NOTATION:    atype = @"NOTATION";    break;
1358       
1359       default:
1360         [NSException raise:@"InvalidAttributeType"
1361                      format:@"don't know attr type with code %i", type];
1362     }
1363     switch (def) {
1364       case XML_ATTRIBUTE_NONE:     defType = nil;          break;
1365       case XML_ATTRIBUTE_REQUIRED: defType = @"#REQUIRED"; break;
1366       case XML_ATTRIBUTE_IMPLIED:  defType = @"#IMPLIED";  break;
1367       case XML_ATTRIBUTE_FIXED:    defType = @"#FIXED";    break;
1368         
1369       default:
1370         [NSException raise:@"InvalidAttributeDefaultType"
1371                      format:@"don't know attr default type with code %i", def];
1372     }
1373     
1374     [self->declHandler attributeDeclaration:aname elementName:ename
1375                        type:atype
1376                        defaultType:defType defaultValue:defValue];
1377     [ename release];
1378     [aname release];
1379     [defValue release];
1380   }
1381 }
1382
1383 #if 0
1384 static int isStandalone(libxmlSAXDriver *self) {
1385 }
1386 static int hasInternalSubset(libxmlSAXDriver *self) {
1387 }
1388 static int hasExternalSubset(libxmlSAXDriver *self) {
1389 }
1390 #endif
1391
1392 static void _externalSubset(libxmlSAXDriver *ctx, const xmlChar *name,
1393                            const xmlChar *ExternalID, const xmlChar *SystemID)
1394 {
1395 }
1396 static void _internalSubset(libxmlSAXDriver *ctx, const xmlChar *name,
1397                            const xmlChar *ExternalID, const xmlChar *SystemID)
1398 {
1399 }
1400
1401 static void _reference(libxmlSAXDriver *ctx, const xmlChar *name) {
1402 #if 0
1403   NSString *refName;
1404
1405   refName = xmlCharsToString(name);
1406   NSLog(@"reference: '%@'", refName);
1407   [refName release];
1408 #endif
1409 }
1410
1411 @end /* libxmlSAXDriver */
1412
1413 #include "unicode.h"