Fox error in last commit. Add parser improvements.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@27963 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2009-02-23 20:51:20 +00:00
parent 30cf8bf35b
commit 8b5ee69ee1
2 changed files with 99 additions and 29 deletions

View file

@ -725,7 +725,7 @@ _NSFoundationUncaughtExceptionHandler (NSException *exception)
static NSUncaughtExceptionHandler *_NSUncaughtExceptionHandler static NSUncaughtExceptionHandler *_NSUncaughtExceptionHandler
= _NSFoundationUncaughtExceptionHandler; = _NSFoundationUncaughtExceptionHandler;
#if defined(_NATIVE_OBJC_EXCEPTIONS) && defined(HAVE_UNEXPECTED) #if !defined(_NATIVE_OBJC_EXCEPTIONS) || defined(HAVE_UNEXPECTED)
static void static void
callUncaughtHandler(id value) callUncaughtHandler(id value)
{ {

View file

@ -626,7 +626,9 @@ typedef struct NSXMLParserIvarsType
IMP didEndMappingPrefix; IMP didEndMappingPrefix;
IMP didStartElement; IMP didStartElement;
IMP didStartMappingPrefix; IMP didStartMappingPrefix;
IMP foundCDATA;
IMP foundCharacters; IMP foundCharacters;
IMP foundComment;
} NSXMLParserIvars; } NSXMLParserIvars;
@ -634,7 +636,9 @@ static SEL didEndElementSel = 0;
static SEL didEndMappingPrefixSel; static SEL didEndMappingPrefixSel;
static SEL didStartElementSel; static SEL didStartElementSel;
static SEL didStartMappingPrefixSel; static SEL didStartMappingPrefixSel;
static SEL foundCDATASel;
static SEL foundCharactersSel; static SEL foundCharactersSel;
static SEL foundCommentSel;
@implementation SloppyXMLParser @implementation SloppyXMLParser
@ -662,8 +666,12 @@ typedef struct { @defs(NSXMLParser) } *xp;
= @selector(parser:didStartElement:namespaceURI:qualifiedName:attributes:); = @selector(parser:didStartElement:namespaceURI:qualifiedName:attributes:);
didStartMappingPrefixSel didStartMappingPrefixSel
= @selector(parser:didStartMappingPrefix:toURI:); = @selector(parser:didStartMappingPrefix:toURI:);
foundCDATASel
= @selector(parser:foundCDATA:);
foundCharactersSel foundCharactersSel
= @selector(parser:foundCharacters:); = @selector(parser:foundCharacters:);
foundCommentSel
= @selector(parser:foundComment:);
} }
} }
@ -774,6 +782,16 @@ typedef struct { @defs(NSXMLParser) } *xp;
this->didStartMappingPrefix = 0; this->didStartMappingPrefix = 0;
} }
if ([_del respondsToSelector: foundCDATASel])
{
this->foundCDATA
= [_del methodForSelector: foundCDATASel];
}
else
{
this->foundCDATA = 0;
}
if ([_del respondsToSelector: foundCharactersSel]) if ([_del respondsToSelector: foundCharactersSel])
{ {
this->foundCharacters this->foundCharacters
@ -783,6 +801,16 @@ typedef struct { @defs(NSXMLParser) } *xp;
{ {
this->foundCharacters = 0; this->foundCharacters = 0;
} }
if ([_del respondsToSelector: foundCommentSel])
{
this->foundComment
= [_del methodForSelector: foundCommentSel];
}
else
{
this->foundComment = 0;
}
} }
} }
@ -798,17 +826,26 @@ typedef struct { @defs(NSXMLParser) } *xp;
#define cget() ((this->cp < this->cend)?(this->column++, *this->cp++): -1) #define cget() ((this->cp < this->cend)?(this->column++, *this->cp++): -1)
- (BOOL) _parseError: (NSString *)message - (BOOL) _parseError: (NSString *)message code: (NSInteger)code
{ {
#if EXTRA_DEBUG #if EXTRA_DEBUG
NSLog(@"XML parseError: %@", message); NSLog(@"XML parseError: %@", message);
#endif #endif
NSError *err = nil; NSDictionary *info = nil;
ASSIGN(this->error, err); [this->error release];
this->abort = YES; // break look if (message != nil)
{
info = [[NSDictionary alloc] initWithObjectsAndKeys:
message, NSLocalizedFailureReasonErrorKey, nil];
}
this->error = [[NSError alloc] initWithDomain: NSXMLParserErrorDomain
code: code
userInfo: info];
[info release];
this->abort = YES;
if ([_del respondsToSelector: @selector(parser:parseErrorOccurred:)]) if ([_del respondsToSelector: @selector(parser:parseErrorOccurred:)])
[_del parser: self parseErrorOccurred: this->error]; // pass error [_del parser: self parseErrorOccurred: this->error];
return NO; return NO;
} }
@ -925,15 +962,6 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
#endif #endif
return; return;
} }
else if ([tag isEqualToString: @"!CDATA"])
{
// pass through as NSData
// parser: foundCDATA:
#if EXTRA_DEBUG
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
#endif
return;
}
else else
{ {
NSMutableDictionary *ns = nil; NSMutableDictionary *ns = nil;
@ -1036,7 +1064,8 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
{ {
[self _parseError: [NSString stringWithFormat: [self _parseError: [NSString stringWithFormat:
@"tag nesting error (</%@> expected, </%@> found)", @"tag nesting error (</%@> expected, </%@> found)",
[this->tagPath lastObject], tag]]; [this->tagPath lastObject], tag]
code: NSXMLParserNotWellBalancedError];
return; return;
} }
[self _closeLastTag]; [self _closeLastTag];
@ -1186,7 +1215,8 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|| strncmp((char *)this->cp, "<?xml ", 6) != 0)) || strncmp((char *)this->cp, "<?xml ", 6) != 0))
{ {
// not a valid XML document start // not a valid XML document start
return [self _parseError: @"missing <?xml > preamble"]; return [self _parseError: @"missing <?xml > preamble"
code: NSXMLParserDocumentStartError];
} }
c = cget(); // get first character c = cget(); // get first character
while (!this->abort) while (!this->abort)
@ -1243,7 +1273,8 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
{ {
/* strict XML nesting error /* strict XML nesting error
*/ */
return [self _parseError: @"unexpected end of file"]; return [self _parseError: @"unexpected end of file"
code: NSXMLParserNotWellBalancedError];
} }
while ([this->tagPath count] > 0) while ([this->tagPath count] > 0)
{ {
@ -1274,7 +1305,8 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
if ([self _parseEntity: &entity] == NO) if ([self _parseEntity: &entity] == NO)
{ {
return [self _parseError: @"empty entity name"]; return [self _parseError: @"empty entity name"
code: NSXMLParserEntityRefAtEOFError];
} }
if (this->foundCharacters != 0) if (this->foundCharacters != 0)
{ {
@ -1300,19 +1332,53 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
/* start of comment skip all characters until "-->" /* start of comment skip all characters until "-->"
*/ */
this->cp += 3; this->cp += 3;
tp = this->cp;
while (this->cp < this->cend-3 while (this->cp < this->cend-3
&& strncmp((char *)this->cp, "-->", 3) != 0) && strncmp((char *)this->cp, "-->", 3) != 0)
{ {
this->cp++; // search this->cp++; // search
} }
/* if _del responds to parser: foundComment: if (this->foundComment != 0)
* convert to string (tp+4 ... cp) {
*/ NSString *c = NewUTF8STR(tp, this->cp - tp);
this->cp += 3; // might go beyond cend but does not care
vp = this->cp; // value might continue (*this->foundComment)(_del,
c = cget(); // get first character behind comment foundCommentSel, self, c);
[c release];
}
this->cp += 3; // might go beyond cend ... ok
vp = this->cp; // value might continue
c = cget(); // get first character after comment
continue; continue;
} }
if (this->cp < this->cend-8
&& strncmp((char *)this->cp, "![CDATA[", 8) == 0)
{
/* start of CDATA skip all characters until "]>"
*/
this->cp += 8;
tp = this->cp;
while (this->cp < this->cend-3
&& strncmp((char *)this->cp, "]]>", 3) != 0)
{
this->cp++; // search
}
if (this->foundCDATA != 0)
{
NSData *d;
d = [[NSData alloc] initWithBytes: tp
length: this->cp - tp];
(*this->foundCDATA)(_del,
foundCDATASel, self, d);
[d release];
}
this->cp += 3; // might go beyond cend ... ok
vp = this->cp; // value might continue
c = cget(); // get first character after CDATA
continue;
}
c = cget(); // get first character of tag c = cget(); // get first character of tag
if (c == '/') if (c == '/')
{ {
@ -1361,7 +1427,8 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
c = cget(); c = cget();
if (c != '>') if (c != '>')
{ {
return [self _parseError: @"<tag/ is missing the >"]; return [self _parseError: @"<tag/ is missing the >"
code: NSXMLParserGTRequiredError];
} }
[self _processTag: tag [self _processTag: tag
isEnd: NO isEnd: NO
@ -1377,7 +1444,8 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
if (c != '>') if (c != '>')
{ {
return [self _parseError: return [self _parseError:
@"<?tag ...? is missing the >"]; @"<?tag ...? is missing the >"
code: NSXMLParserGTRequiredError];
} }
// process // process
[self _processTag: tag [self _processTag: tag
@ -1405,7 +1473,8 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
#endif #endif
if (!this->acceptHTML && [arg length] == 0) if (!this->acceptHTML && [arg length] == 0)
{ {
return [self _parseError: @"empty attribute name"]; return [self _parseError: @"empty attribute name"
code: NSXMLParserAttributeNotStartedError];
} }
c = cget(); // get delimiting character c = cget(); // get delimiting character
if (c == '=') if (c == '=')
@ -1432,7 +1501,8 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
} }
} }
} }
return [self _parseError: @"this->aborted"]; // this->aborted return [self _parseError: @"this->aborted"
code: NSXMLParserDelegateAbortedParseError];
} }
- (BOOL) acceptsHTML - (BOOL) acceptsHTML