New message handling features for libxml wrapper

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@16773 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2003-05-22 17:00:03 +00:00
parent 594324c1dc
commit 8ab113e4b6
5 changed files with 152 additions and 13 deletions

View file

@ -3,6 +3,12 @@
* Source/Additions/GSXML.m: ([GSXPathContext-evaluateExpression:])
Test for NULL return from libxml and return nil rather than trying
to dereference the null pointer.
New features to record error and warning messages added.
* Headers/Foundation/GSXML.h: ([GSXMLParser-messages]) returns saved
messages. ([GSXMLParser-saveMessages:]) Says whether to save messages
or write to stderr.
* Source/Additions/GSObjCRuntime.m: Hack to fix type clash in
declaration of __objc_exec_class()
2003-05-19 Adam Fedor <fedor@gnu.org>

View file

@ -154,9 +154,10 @@
@interface GSXMLParser : NSObject
{
id src; /* source for parsing */
void *lib; /* parser context */
GSSAXHandler *saxHandler;
id src; /* source for parsing */
void *lib; /* parser context */
GSSAXHandler *saxHandler; /* handler for parsing */
NSMutableString *messages; /* append messages here */
}
+ (NSString*) loadEntity: (NSString*)publicId at: (NSString*)location;
+ (GSXMLParser*) parser;
@ -185,8 +186,10 @@
withData: (NSData*)data;
- (BOOL) keepBlanks: (BOOL)yesno;
- (NSMutableString*) messages;
- (BOOL) parse;
- (BOOL) parse: (NSData*)data;
- (void) saveMessages: (BOOL)yesno;
- (BOOL) substituteEntities: (BOOL)yesno;
@end
@ -273,6 +276,9 @@
@end
@interface GSTreeSAXHandler : GSSAXHandler
@end
@interface GSHTMLSAXHandler : GSSAXHandler
@end

View file

@ -48,7 +48,6 @@
#include "gnustep/base/GNUstep.h"
#include <string.h>
@class NSNull;
/** Deprecated ... use GSObjCFindVariable() */
@ -420,7 +419,7 @@ GSObjCAddClasses(NSArray *classes)
void
GSObjCAddClasses(NSArray *classes)
{
void __objc_exec_class (Module_t module);
void __objc_exec_class (void* module);
void __objc_resolve_class_links ();
Module_t module;
Symtab_t symtab;
@ -835,6 +834,7 @@ GSObjCAddClassBehavior(Class receiver, Class behavior)
#include <Foundation/NSKeyValueCoding.h>
#endif
/** Deprecated ... use GSObjCGetValue() */
id
GSGetValue(NSObject *self, NSString *key, SEL sel,

View file

@ -1806,6 +1806,7 @@ static NSString *endMarker = @"At end of incremental parse";
- (void) dealloc
{
RELEASE(messages);
RELEASE(src);
RELEASE(saxHandler);
if (lib != NULL)
@ -1864,14 +1865,15 @@ static NSString *endMarker = @"At end of incremental parse";
return [self initWithSAXHandler: nil];
}
/**
/** <init />
* <p>
* Initialisation of a new Parser with SAX handler (if not nil).
* Initialisation of a new Parser with SAX handler.
* </p>
* <p>
* If the handler object supplied is nil, the parser will build
* a tree representing the parsed file rather than attempting
* to get the handler to deal with the parsed elements and entities.
* If the handler object supplied is nil, the parser will use
* an instance of [GSTreeSAXHandler] to build a tree representing
* the parsed file. This tree will then be available (via the -document
* method) as a [GSXMLDocument] on completion of parsing.
* </p>
* <p>
* The source for the parsing process is not specified - so
@ -1881,13 +1883,20 @@ static NSString *endMarker = @"At end of incremental parse";
*/
- (id) initWithSAXHandler: (GSSAXHandler*)handler
{
if (handler != nil && [handler isKindOfClass: [GSSAXHandler class]] == NO)
if (handler == nil)
{
saxHandler = [GSTreeSAXHandler new];
}
else if ([handler isKindOfClass: [GSSAXHandler class]] == YES)
{
saxHandler = RETAIN(handler);
}
else
{
NSLog(@"Bad GSSAXHandler object passed to GSXMLParser initialiser");
RELEASE(self);
return nil;
}
saxHandler = RETAIN(handler);
[saxHandler _setParser: self];
if ([self _initLibXML] == NO)
{
@ -1972,6 +1981,15 @@ static NSString *endMarker = @"At end of incremental parse";
return self;
}
/**
* Returns the string into which warning and error messages are saved,
* or nil if they are being written to stderr.
*/
- (NSMutableString*) messages
{
return messages;
}
/**
* Set and return the previous value for blank text nodes support.
* ignorableWhitespace nodes are only generated when running
@ -2126,6 +2144,25 @@ static NSString *endMarker = @"At end of incremental parse";
}
}
/**
* Sets up (or removes) a mutable string to which error and warning
* messages are saved. Using an argument of NO will cause these messages
* to be written to stderr (the default).<br />
* NB. A SAX handler which overrides the error and warning logging
* messages may stop this mechanism operating.
*/
- (void) saveMessages: (BOOL)yesno
{
if (yesno == YES)
{
ASSIGN(messages, [NSMutableString stringWithCapacity: 256]);
}
else
{
DESTROY(messages);
}
}
/**
* Set and return the previous value for entity support.
* Initially the parser always keeps entity references instead
@ -2918,6 +2955,7 @@ fatalErrorFunction(void *ctx, const char *msg, ...)
*/
- (void) warning: (NSString*)e
{
GSPrintf(stderr, @"%@", e);
}
/**
@ -2925,6 +2963,7 @@ fatalErrorFunction(void *ctx, const char *msg, ...)
*/
- (void) error: (NSString*)e
{
GSPrintf(stderr, @"%@", e);
}
/**
@ -2932,6 +2971,7 @@ fatalErrorFunction(void *ctx, const char *msg, ...)
*/
- (void) fatalError: (NSString*)e
{
GSPrintf(stderr, @"%@", e);
}
/**
@ -3028,7 +3068,7 @@ fatalErrorFunction(void *ctx, const char *msg, ...)
}
else
{
memcpy(lib, &xmlDefaultSAXHandler, sizeof(htmlSAXHandler));
memcpy(lib, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
#define LIB ((xmlSAXHandlerPtr)lib)
LIB->internalSubset = (void*) internalSubsetFunction;
@ -3067,6 +3107,91 @@ fatalErrorFunction(void *ctx, const char *msg, ...)
}
@end
/**
* The default handler for parsing documents ... this will build a
* GSXMLDocument for you. This handler may not currently be subclassed,
* though that capability may be added at a later date.
*/
@implementation GSTreeSAXHandler
/**
* Called when a warning message needs to be output.<br />
* See [GSXMLParser-setErrors:] for the mechanism implemented by this.
*/
- (void) warning: (NSString*)e
{
NSMutableString *m = [parser messages];
if (m == nil)
{
GSPrintf(stderr, @"%@", e);
}
else
{
[m appendString: e];
}
}
/**
* Called when an error message needs to be output.<br />
* See [GSXMLParser-setErrors:] for the mechanism implemented by this.
*/
- (void) error: (NSString*)e
{
NSMutableString *m = [parser messages];
if (m == nil)
{
GSPrintf(stderr, @"%@", e);
}
else
{
[m appendString: e];
}
}
/**
* Called when a fatal error message needs to be output.<br />
* See [GSXMLParser-setErrors:] for the mechanism implemented by this.
*/
- (void) fatalError: (NSString*)e
{
NSMutableString *m = [parser messages];
if (m == nil)
{
GSPrintf(stderr, @"%@", e);
}
else
{
[m appendString: e];
}
}
- (BOOL) _initLibXML
{
lib = (xmlSAXHandler*)malloc(sizeof(xmlSAXHandler));
if (lib == NULL)
{
return NO;
}
else
{
memcpy(lib, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
#define LIB ((xmlSAXHandlerPtr)lib)
LIB->warning = (void*) warningFunction;
LIB->error = (void*) errorFunction;
LIB->fatalError = (void*) fatalErrorFunction;
#undef LIB
return YES;
}
}
@end
/**
* You may create a subclass of this class to handle incremental parsing
* of html documents ... this is provided for handling legacy documents,

View file

@ -94,9 +94,11 @@ main(int argc, char **argv, char **env)
[parser substituteEntities: NO];
[parser doValidityChecking: YES];
[parser keepBlanks: NO];
[parser saveMessages: YES];
if ([parser parse] == NO)
{
NSLog(@"WARNING %@ is not a valid document", file);
NSLog(@"Errors: %@", [parser messages]);
}
root = [[parser document] root];
NSLog(@"Document is %@", [root name]);