diff --git a/ChangeLog b/ChangeLog index f86a69e5d..ab1603df4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2004-05-18 Richard Frith-Macdonald + + * configure.ac: Check for SAX2 + * Headers/Additions/GNUstepBase/GSXML.h: Add SAX2 methods + * Headers/Additions/GNUstepBase/config.h.in: Add SAX2 header + * Source/Additions/GSXML.m: Add SAX2 methods and remove + use of deprecated functionality if recent (SAX2) API is + available to use instead. + 2004-05-17 Richard Frith-Macdonald * Source/NSMessagePort.m: diff --git a/Headers/Additions/GNUstepBase/GSXML.h b/Headers/Additions/GNUstepBase/GSXML.h index 301ebae32..566b88167 100644 --- a/Headers/Additions/GNUstepBase/GSXML.h +++ b/Headers/Additions/GNUstepBase/GSXML.h @@ -176,6 +176,7 @@ withData: (NSData*)data; + (NSString*) xmlEncodingStringForStringEncoding: (NSStringEncoding)encoding; +- (int) columnNumber; - (GSXMLDocument*) document; - (BOOL) doValidityChecking: (BOOL)yesno; - (int) errNo; @@ -189,11 +190,14 @@ withData: (NSData*)data; - (BOOL) keepBlanks: (BOOL)yesno; +- (int) lineNumber; - (NSString*) messages; - (BOOL) parse; - (BOOL) parse: (NSData*)data; +- (NSString*) publicID; - (void) saveMessages: (BOOL)yesno; - (BOOL) substituteEntities: (BOOL)yesno; +- (NSString*) systemID; @end @@ -228,6 +232,9 @@ type: (int)type; - (void) endDocument; - (void) endElement: (NSString*)elementName; +- (void) endElement: (NSString*)elementName + prefix: (NSString*)prefix + href: (NSString*)href; - (void) entityDecl: (NSString*)name type: (int)type public: (NSString*)publicId @@ -270,6 +277,10 @@ - (void) startDocument; - (void) startElement: (NSString*)elementName attributes: (NSMutableDictionary*)elementAttributes; +- (void) startElement: (NSString*)elementName + prefix: (NSString*)prefix + href: (NSString*)href + attributes: (NSMutableDictionary*)elementAttributes; - (void) unparsedEntityDecl: (NSString*)name public: (NSString*)publicId system: (NSString*)systemId diff --git a/Headers/Additions/GNUstepBase/config.h.in b/Headers/Additions/GNUstepBase/config.h.in index fc3f5303b..1a16a1722 100644 --- a/Headers/Additions/GNUstepBase/config.h.in +++ b/Headers/Additions/GNUstepBase/config.h.in @@ -106,6 +106,9 @@ /* Define if libxml available */ #undef HAVE_LIBXML +/* Define if libxml/SAX2.h available */ +#undef HAVE_LIBXML_SAX2_H + /* Define if libxslt available */ #undef HAVE_LIBXSLT diff --git a/Source/Additions/GSXML.m b/Source/Additions/GSXML.m index 8d37c1ae9..edc37fc02 100644 --- a/Source/Additions/GSXML.m +++ b/Source/Additions/GSXML.m @@ -65,7 +65,14 @@ #include #include #include -#include +#ifdef HAVE_LIBXML_SAX2_H +#include +#else +# define xmlSAX2GetColumnNumber getColumnNumber +# define xmlSAX2GetLineNumber getLineNumber +# define xmlSAX2GetPublicId getPublicId +# define xmlSAX2GetSystemId getSystemId +#endif #include #include #include @@ -1887,6 +1894,14 @@ static NSString *endMarker = @"At end of incremental parse"; return xmlEncodingString; } +/** + * If executed during a parse operation, returns the current column number. + */ +- (int) columnNumber +{ + return xmlSAX2GetColumnNumber(lib); +} + - (void) dealloc { NSHashRemove(warnings, self); @@ -1906,12 +1921,11 @@ static NSString *endMarker = @"At end of incremental parse"; */ - (BOOL) doValidityChecking: (BOOL)yesno { - int oldVal; - int newVal = (yesno == YES) ? 1 : 0; + BOOL old; - xmlGetFeature((xmlParserCtxtPtr)lib, "validate", (void*)&oldVal); - xmlSetFeature((xmlParserCtxtPtr)lib, "validate", (void*)&newVal); - return (oldVal == 1) ? YES : NO; + old = (((xmlParserCtxtPtr)lib)->validate) ? YES : NO; + ((xmlParserCtxtPtr)lib)->validate = (yesno ? 1 : 0); + return old; } /** @@ -2079,15 +2093,6 @@ 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. - */ -- (NSString*) messages -{ - return messages; -} - /** * Set and return the previous value for blank text nodes support. * ignorableWhitespace nodes are only generated when running @@ -2096,12 +2101,28 @@ static NSString *endMarker = @"At end of incremental parse"; */ - (BOOL) keepBlanks: (BOOL)yesno { - int oldVal; - int newVal = (yesno == YES) ? 1 : 0; + BOOL old; - xmlGetFeature((xmlParserCtxtPtr)lib, "keep blanks", (void*)&oldVal); - xmlSetFeature((xmlParserCtxtPtr)lib, "keep blanks", (void*)&newVal); - return (oldVal == 1) ? YES : NO; + old = (((xmlParserCtxtPtr)lib)->keepBlanks) ? YES : NO; + ((xmlParserCtxtPtr)lib)->keepBlanks = (yesno ? 1 : 0); + return old; +} + +/** + * If executed during a parse operation, returns the current line number. + */ +- (int) lineNumber +{ + return xmlSAX2GetLineNumber(lib); +} + +/** + * Returns the string into which warning and error messages are saved, + * or nil if they are being written to stderr. + */ +- (NSString*) messages +{ + return messages; } /** @@ -2242,6 +2263,14 @@ static NSString *endMarker = @"At end of incremental parse"; } } +/** + * Return the public ID of the document being parsed. + */ +- (NSString*) publicID +{ + return UTF8Str(xmlSAX2GetPublicId(lib)); +} + /** * Sets up (or removes) a mutable string to which error and warning * messages are saved. Using an argument of NO will cause these messages @@ -2268,34 +2297,19 @@ static NSString *endMarker = @"At end of incremental parse"; */ - (BOOL) substituteEntities: (BOOL)yesno { - int oldVal; - int newVal = (yesno == YES) ? 1 : 0; + BOOL old; - xmlGetFeature((xmlParserCtxtPtr)lib, "substitute entities", (void*)&oldVal); - if (xmlSetFeature((xmlParserCtxtPtr)lib, "substitute entities", - (void*)&newVal) < 0) - [NSException raise: NSInternalInconsistencyException - format: @"Unable to set substituteEntities"]; + old = (((xmlParserCtxtPtr)lib)->replaceEntities) ? YES : NO; + ((xmlParserCtxtPtr)lib)->replaceEntities = (yesno ? 1 : 0); + return old; +} - newVal = -1; - if (xmlGetFeature((xmlParserCtxtPtr)lib, "substitute entities", - (void*)&newVal) < 0) - [NSException raise: NSInternalInconsistencyException - format: @"Unable to get substituteEntities"]; - if (yesno == YES) - { - if (newVal != 1) - [NSException raise: NSInternalInconsistencyException - format: @"Unable to set substituteEntities to 1"]; - } - else - { - if (newVal != 0) - [NSException raise: NSInternalInconsistencyException - format: @"Unable to set substituteEntities to 0"]; - } - xmlSubstituteEntitiesDefault(newVal); // Set default too. - return (oldVal == 1) ? YES : NO; +/** + * Return the system ID of the document being parsed. + */ +- (NSString*) systemID +{ + return UTF8Str(xmlSAX2GetSystemId(lib)); } /* @@ -2886,6 +2900,56 @@ endElementFunction(void *ctx, const unsigned char *name) } } +#if HAVE_LIBXML_SAX2_H +static void +startElementNsFunction(void *ctx, const unsigned char *name, + const unsigned char *prefix, const unsigned char *href, + int nb_namespaces, const unsigned char **namespaces, + int nb_attributes, int nb_defaulted, + const unsigned char **atts) +{ + START(startElement:prefix:href:attributes:, void, (id,SEL,id,id,id,id)); + + if (imp != treeImp) + { + int i; + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + NSString *key, *obj; + + if (atts != NULL) + { + for (i = 0; (atts[i] != NULL); i++) + { + key = UTF8Str(atts[i++]); + obj = UTF8Str(atts[i]); + [dict setObject: obj forKey: key]; + } + } + (*imp)(HANDLER, sel, UTF8Str(name), UTF8Str(prefix), UTF8Str(href), dict); + } + else + { + xmlSAX2StartElementNs(ctx, name, prefix, href, nb_namespaces, namespaces, nb_attributes, nb_defaulted, atts); + } +} + +static void +endElementNsFunction(void *ctx, const unsigned char *name, + const unsigned char *prefix, const unsigned char *href) +{ + START(endElement:, void, (id,SEL,id,id,id)); + + if (imp != treeImp) + { + (*imp)(HANDLER, sel, UTF8Str(name), UTF8Str(prefix), UTF8Str(href)); + } + else + { + xmlSAX2EndElementNs(ctx, name, prefix, href); + } +} +#endif + static void charactersFunction(void *ctx, const unsigned char *ch, int len) { @@ -2991,7 +3055,7 @@ warningFunction(void *ctx, const unsigned char *msg, ...) NSCAssert(ctx,@"No Context"); lineNumber = getLineNumber(ctx); - colNumber = getColumnNumber(ctx); + colNumber = xmlSAX2GetColumnNumber(ctx); [HANDLER warning: estr colNumber: colNumber lineNumber: lineNumber]; @@ -3009,8 +3073,8 @@ errorFunction(void *ctx, const unsigned char *msg, ...) estr = [[NSString alloc] initWithFormat: UTF8Str(msg) arguments: args]; va_end(args); NSCAssert(ctx,@"No Context"); - lineNumber = getLineNumber(ctx); - colNumber = getColumnNumber(ctx); + lineNumber = xmlSAX2GetLineNumber(ctx); + colNumber = xmlSAX2GetColumnNumber(ctx); [HANDLER error: estr colNumber: colNumber lineNumber: lineNumber]; @@ -3028,8 +3092,8 @@ fatalErrorFunction(void *ctx, const unsigned char *msg, ...) estr = [[NSString alloc] initWithFormat: UTF8Str(msg) arguments: args]; va_end(args); NSCAssert(ctx, @"No Context"); - lineNumber = getLineNumber(ctx); - colNumber = getColumnNumber(ctx); + lineNumber = xmlSAX2GetLineNumber(ctx); + colNumber = xmlSAX2GetColumnNumber(ctx); [HANDLER fatalError: estr colNumber: colNumber lineNumber: lineNumber]; @@ -3118,10 +3182,26 @@ fatalErrorFunction(void *ctx, const unsigned char *msg, ...) { } +- (void) startElement: (NSString*)elementName + prefix: (NSString*)prefix + href: (NSString*)href + attributes: (NSMutableDictionary*)elementAttributes +{ +} + /** * Called when a closing tag has been processed. */ -- (void) endElement: (NSString*) elementName +- (void) endElement: (NSString*)elementName +{ +} + +/** + * Called when a closing tag has been processed. + */ +- (void) endElement: (NSString*)elementName + prefix: (NSString*)prefix + href: (NSString*)href { } @@ -3392,6 +3472,10 @@ fatalErrorFunction(void *ctx, const unsigned char *msg, ...) LIB->endDocument = (void*) endDocumentFunction; LIB->startElement = (void*) startElementFunction; LIB->endElement = (void*) endElementFunction; +#if HAVE_LIBXML_SAX2_H + LIB->startElementNs = (void*) startElementNsFunction; + LIB->endElementNs = (void*) endElementNsFunction; +#endif LIB->reference = (void*) referenceFunction; LIB->characters = (void*) charactersFunction; LIB->ignorableWhitespace = (void*) ignorableWhitespaceFunction; @@ -3402,6 +3486,9 @@ fatalErrorFunction(void *ctx, const unsigned char *msg, ...) LIB->fatalError = (void*) fatalErrorFunction; LIB->getParameterEntity = (void*) getParameterEntityFunction; LIB->cdataBlock = (void*) cdataBlockFunction; +#if HAVE_LIBXML_SAX2_H + xmlSAXVersion(LIB, 2); // Set SAX2 +#endif #undef LIB return YES; } @@ -3422,7 +3509,7 @@ fatalErrorFunction(void *ctx, const unsigned char *msg, ...) @implementation GSTreeSAXHandler /** - * Called when a warning message needs to be output.
+: Cal]led when a warning message needs to be output.
* See [GSXMLParser-setErrors:] for the mechanism implemented by this. */ - (void) warning: (NSString*)e diff --git a/configure b/configure index 03af9b677..110579b76 100755 --- a/configure +++ b/configure @@ -13973,6 +13973,155 @@ cat >>confdefs.h <<\_ACEOF #define HAVE_LIBXML 1 _ACEOF + +for ac_header in libxml/SAX2.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + #-------------------------------------------------------------------- # Check for (optional) libxslt #-------------------------------------------------------------------- diff --git a/configure.ac b/configure.ac index ca73a7005..e0a9e3ada 100644 --- a/configure.ac +++ b/configure.ac @@ -992,6 +992,7 @@ if test $enable_xml = yes; then LIBS="$LIBS $XML_LIBS" HAVE_LIBXML=1 AC_DEFINE(HAVE_LIBXML,1,[Define if libxml available]) + AC_CHECK_HEADERS(libxml/SAX2.h) #-------------------------------------------------------------------- # Check for (optional) libxslt #--------------------------------------------------------------------