Index: ChangeLog
==================================================================
--- ChangeLog
+++ ChangeLog
@@ -1,9 +1,29 @@
Legend:
* Changes of existing features or bugfixes.
+ New features.
+ObjFW 0.4-alpha1 -> ObjFW 0.5, 09.04.2011
+ + %@ is now allowed in format strings.
+ + Added of_log for easy logging.
+ * Exceptions have one header per exception now.
+ * Lots of exception improvements.
+ * Huge improvements in XML handling.
+ * Improvements in socket handling, including improved API.
+ * OFStreamObserver is now thread-safe and stops the current observe call when
+ the set of streams to observe is modified.
+ + New class OFURL.
+ + New class OFHTTPRequest.
+ + New class OFCondition.
+ * Improvements in objfw-compile.
+ + Blocks can be used together with Cocoa now.
+ + When linking ObjFW and Cocoa, OFAutoreleasePools are used by both now.
+ + Support for Base64.
+ + Use a real Xcode project instead of just calling make.
+ + Add Haiku to the list of supported platforms.
+ * Lots of small bugfixes and countless small changes. Read the commits!
+
ObjFW 0.3.1 -> 0.4-alpha1, 03.01.2011
* ObjFW is now available under the terms of the QPL, GPLv2 and GPLv3.
+ Support for blocks was added, including a blocks runtime.
+ Added support for the new GNU runtime, introduced in GCC 4.6.
* Objects returned from collections are no longer retained and autoreleased.
Index: Info.plist
==================================================================
--- Info.plist
+++ Info.plist
@@ -15,10 +15,10 @@
CFBundlePackageType
FMWK
CFBundleSignature
OBJFW
CFBundleVersion
- 0.4-dev
+ 0.6-dev
CFBundleShortVersionString
- 0.4-dev
+ 0.6-dev
Index: configure.ac
==================================================================
--- configure.ac
+++ configure.ac
@@ -1,6 +1,6 @@
-AC_INIT(ObjFW, 0.4-dev, js@webkeks.org)
+AC_INIT(ObjFW, 0.6-dev, js@webkeks.org)
AC_CONFIG_SRCDIR(src)
AS_IF([test x"$host" = x"psp"], [
OBJCFLAGS="-G0 $OBJCFLAGS"
LIBS="$LIBS -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc"
Index: extra.mk.in
==================================================================
--- extra.mk.in
+++ extra.mk.in
@@ -1,8 +1,8 @@
OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@
OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@
-OBJFW_LIB_MAJOR = 3
+OBJFW_LIB_MAJOR = 4
OBJFW_LIB_MINOR = 0
OBJFW_LIB_MAJOR_MINOR = ${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR}
ASPRINTF_M = @ASPRINTF_M@
ATOMIC_H = @ATOMIC_H@
Index: src/OFXMLParser.h
==================================================================
--- src/OFXMLParser.h
+++ src/OFXMLParser.h
@@ -177,10 +177,11 @@
of_xml_parser_string_block_t CDATAHandler;
of_xml_parser_string_block_t commentHandler;
of_xml_parser_unknown_entity_block_t unknownEntityHandler;
#endif
size_t level;
+ BOOL acceptProlog;
size_t lineNumber;
BOOL lastCarriageReturn;
BOOL finishedParsing;
}
Index: src/OFXMLParser.m
==================================================================
--- src/OFXMLParser.m
+++ src/OFXMLParser.m
@@ -49,11 +49,11 @@
[cache replaceOccurrencesOfString: @"\r"
withString: @"\n"];
return [cache stringByXMLUnescapingWithDelegate: delegate];
}
-static OF_INLINE OFString*
+static OFString*
namespace_for_prefix(OFString *prefix, OFArray *namespaces)
{
OFDictionary **carray = [namespaces cArray];
ssize_t i;
@@ -155,10 +155,11 @@
dict = [OFMutableDictionary dictionaryWithKeysAndObjects:
@"xml", @"http://www.w3.org/XML/1998/namespace",
@"xmlns", @"http://www.w3.org/2000/xmlns/", nil];
[namespaces addObject: dict];
+ acceptProlog = YES;
lineNumber = 1;
[pool release];
} @catch (id e) {
[self release];
@@ -265,11 +266,11 @@
}
}
/*
* The following methods handle the different states of the parser. They are
- * lookup up in +[initialize] and put in a lookup table to speed things up.
+ * looked up in +[initialize] and put in a lookup table to speed things up.
* One dispatch for every character would be way too slow!
*/
/* Not in a tag */
- (void)_parseOutsideTagWithBuffer: (const char*)buf
@@ -276,12 +277,13 @@
i: (size_t*)i
last: (size_t*)last
{
size_t len;
- if (finishedParsing && buf[*i] != ' ' && buf[*i] != '\t' &&
- buf[*i] != '\n' && buf[*i] != '\r' && buf[*i] != '<')
+ if ((finishedParsing || [previous count] < 1) && buf[*i] != ' ' &&
+ buf[*i] != '\t' && buf[*i] != '\n' && buf[*i] != '\r' &&
+ buf[*i] != '<')
@throw [OFMalformedXMLException newWithClass: isa
parser: self];
if (buf[*i] != '<')
return;
@@ -317,11 +319,11 @@
/* Tag was just opened */
- (void)_parseTagOpenedWithBuffer: (const char*)buf
i: (size_t*)i
last: (size_t*)last
{
- if (finishedParsing && buf[*i] != '!')
+ if (finishedParsing && buf[*i] != '!' && buf[*i] != '?')
@throw [OFMalformedXMLException newWithClass: isa
parser: self];
switch (buf[*i]) {
case '?':
@@ -330,23 +332,108 @@
level = 0;
break;
case '/':
*last = *i + 1;
state = OF_XMLPARSER_IN_CLOSE_TAG_NAME;
+ acceptProlog = NO;
break;
case '!':
*last = *i + 1;
state = OF_XMLPARSER_IN_EXCLAMATIONMARK;
+ acceptProlog = NO;
break;
default:
state = OF_XMLPARSER_IN_TAG_NAME;
+ acceptProlog = NO;
(*i)--;
break;
}
}
-/* Inside prolog */
+/* */
+- (BOOL)_parseXMLProcessingInstructions: (OFString*)pi
+{
+ const char *pi_c;
+ size_t i, last, pi_len;
+ int xstate = 0;
+ OFString *attr = nil;
+ OFString *val = nil;
+ char xdelim = 0;
+
+ if (!acceptProlog)
+ return NO;
+
+ acceptProlog = NO;
+
+ pi = [pi substringFromIndex: 3
+ toIndex: [pi length]];
+ pi = [pi stringByDeletingLeadingAndTrailingWhitespaces];
+
+ pi_c = [pi cString];
+ pi_len = [pi cStringLength];
+
+ for (i = last = 0; i < pi_len; i++) {
+ switch (xstate) {
+ case 0:
+ if (pi_c[i] == ' ' || pi_c[i] == '\t' ||
+ pi_c[i] == '\r' || pi_c[i] == '\n')
+ continue;
+
+ last = i;
+ xstate = 1;
+ i--;
+
+ break;
+ case 1:
+ if (pi_c[i] != '=')
+ continue;
+
+ attr = [OFString stringWithCString: pi_c + last
+ length: i - last];
+ last = i + 1;
+ xstate = 2;
+
+ break;
+ case 2:
+ if (pi_c[i] != '\'' && pi_c[i] != '"')
+ return NO;
+
+ xdelim = pi_c[i];
+ last = i + 1;
+ xstate = 3;
+
+ break;
+ case 3:
+ if (pi_c[i] != xdelim)
+ continue;
+
+ val = [OFString stringWithCString: pi_c + last
+ length: i - last];
+
+ if ([attr isEqual: @"version"])
+ if (![val hasPrefix: @"1."])
+ return NO;
+
+ if ([attr isEqual: @"encoding"])
+ if ([val caseInsensitiveCompare: @"utf-8"] !=
+ OF_ORDERED_SAME)
+ return NO;
+
+ last = i + 1;
+ xstate = 0;
+
+ break;
+ }
+ }
+
+ if (xstate != 0)
+ return NO;
+
+ return YES;
+}
+
+/* Inside processing instructions */
- (void)_parseInProcessingInstructionsWithBuffer: (const char*)buf
i: (size_t*)i
last: (size_t*)last
{
if (buf[*i] == '?')
@@ -368,10 +455,18 @@
* Class swizzle the string to be immutable. We pass it as
* OFString*, so it can't be modified anyway. But not swizzling
* it would create a real copy each time -[copy] is called.
*/
pi->isa = [OFString class];
+
+ if ([pi isEqual: @"xml"] || [pi hasPrefix: @"xml "] ||
+ [pi hasPrefix: @"xml\t"] || [pi hasPrefix: @"xml\r"] ||
+ [pi hasPrefix: @"xml\n"])
+ if (![self _parseXMLProcessingInstructions: pi])
+ @throw [OFMalformedXMLException
+ newWithClass: isa
+ parser: self];
[delegate parser: self
foundProcessingInstructions: pi];
[pool release];
Index: tests/OFXMLParserTests.m
==================================================================
--- tests/OFXMLParserTests.m
+++ tests/OFXMLParserTests.m
@@ -374,8 +374,23 @@
OFMalformedXMLException, [parser parseString: @"a"])
EXPECT_EXCEPTION(@"Detection of junk after the document #2",
OFMalformedXMLException, [parser parseString: @""])
+
+ parser = [OFXMLParser parser];
+ EXPECT_EXCEPTION(@"Detection of invalid XML processing instructions #2",
+ OFMalformedXMLException,
+ [parser parseString: @""])
+
+ parser = [OFXMLParser parser];
+ EXPECT_EXCEPTION(@"Detection of invalid XML processing instructions #3",
+ OFMalformedXMLException,
+ [parser parseString: @""])
+
[pool drain];
}
@end
Index: utils/objfw-config.in
==================================================================
--- utils/objfw-config.in
+++ utils/objfw-config.in
@@ -35,11 +35,11 @@
LIBS="-L${libdir} -lobjfw @LIBS@"
PLUGIN_CFLAGS="@PLUGIN_CFLAGS@"
PLUGIN_LDFLAGS="@PLUGIN_LDFLAGS@"
PLUGIN_SUFFIX="@PLUGIN_SUFFIX@"
PROG_SUFFIX="@EXEEXT@"
-VERSION="0.4-dev"
+VERSION="0.6-dev"
show_help() {
cat <<__EOF__
objfw-config: Available arguments are: