ObjFW  Changes On Branch 836314f39ad31a42

Changes In Branch 0.90 Through [836314f39a] Excluding Merge-Ins

This is equivalent to a diff from 636098dbdd to 836314f39a

2017-10-14
18:53
Fix more shadowed variables check-in: a54fb211ea user: js tags: 0.90
2017-10-11
20:59
Fix shadowed variables and enable -Wshadow check-in: 836314f39a user: js tags: 0.90
2017-10-07
15:14
OFThread: Fix setting the name on the wrong thread check-in: 1a502ac38c user: js tags: 0.90
2017-07-29
10:50
Set version to 0.90-dev as 0.90 has been branched check-in: 7e614ef5c0 user: js tags: trunk
10:22
Create 0.90 branch check-in: f934699959 user: js tags: 0.90
2017-07-24
20:33
runtime: Don't depend on platform.h in ObjFW-RT.h check-in: 636098dbdd user: js tags: trunk
20:29
OFINIFile: Always use \r\n check-in: 1248c00475 user: js tags: trunk

Modified ChangeLog from [22a812d84f] to [f57f7a2cc8].

1
2
3















































4
5
6
7
8
9
10
Legend:
 * Changes of existing features or bugfixes
 + New features
















































ObjFW 0.8 -> ObjFW 0.8.1, 04.10.2015
 * Adjust to __nullable / __nonnull being changed to _Nullable / _Nonnull in
   Clang 3.7 (this fixes compilation with Clang 3.7)
 * Blocks: Proper handling when called from a byref handler
 * Fix compilation on Solaris
 * Fix compilation for Wii, PSP and Nintendo DS



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
Legend:
 * Changes of existing features or bugfixes
 + New features

This file only contains the most significant changes.

ObjFW 0.90 -> ObjFW 0.90.1, 20.08.2017
 * OFData: Fix -[description]
 * OFFileManager: Set errno to 0 before readdir()
 * OFDate: Add -[localMinute]
 * OFTarArchiveEntry: Fix prefix handling for ustar
 * OFZIPArchive: Fix uncompressed + data descriptor
 * OFArray: Fix MessagePack encoding
 * of_asprintf: Don't require set up OFLocalization
 * OFGZIPStream: Add missing documentation
 * Fix a linker warning on OpenBSD/SPARC64
 * Remove the OFFile b modes from MorphOS
   (they were already removed for all other OSes)

ObjFW 0.8.1 -> ObjFW 0.90, 01.08.2017
 + New classes: OFFileManager, OFGZIPStream, OFTarArchive, OFTarArchiveEntry
		OFHMAC, OFSandbox, OFHTTPCookie, OFHTTPCookieManager,
		OFLocalization
 + New platforms: Nintendo 3DS, MorphOS
 + New lookup assembly for platforms: SPARC64/ELF, ARM64/ELF
 + New forwarding for: ARM64/ELF
 + New tools: objfw-new (to create boilerplate code)
 + New options: --disable-unicode-tables
 * Required GCC version increased to 4.6
 * OFDataArray was split into OFData and OFMutableData
 * OFURL was split into OFURL and OFMutableURL
 * Most properties are now nonatomic
   (this changes from returned retained + autoreleased to +0 retained)
 * Correct handling of encoding on Win32 console
   (stream is read and written in UTF-8 and translated to UTF-16 on the fly)
 * Runtime is now built as a separate library
 + More encodings for strings
 * Reworked OFOptionsParser API
 * Refactored OFKernelEventObserver
 * Better randomization of HTTP header order
 * Allow overriding all HTTP headers
 * Definition of thread priorities changed
 + Key Value Coding
 + Exceptions in ObjC++
 * OFHash was renamed to OFCryptoHash
 + PBKDF2
 + scrypt
 + Xcode project to build for iOS
 + String decomposition to NFD
 * OFFile modes simplified ('b' removed)

ObjFW 0.8 -> ObjFW 0.8.1, 04.10.2015
 * Adjust to __nullable / __nonnull being changed to _Nullable / _Nonnull in
   Clang 3.7 (this fixes compilation with Clang 3.7)
 * Blocks: Proper handling when called from a byref handler
 * Fix compilation on Solaris
 * Fix compilation for Wii, PSP and Nintendo DS

Modified ObjFW.xcodeproj/project.pbxproj from [b65ec16d37] to [fbe50e44c7].

3799
3800
3801
3802
3803
3804
3805

3806
3807
3808
3809
3810
3811
3812
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = c11;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 2;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
				GCC_WARN_PEDANTIC = YES;

				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				ONLY_ACTIVE_ARCH = YES;
				OTHER_CFLAGS = (
					"-fexceptions",







>







3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = c11;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 2;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
				GCC_WARN_PEDANTIC = YES;
				GCC_WARN_SHADOW = YES;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				ONLY_ACTIVE_ARCH = YES;
				OTHER_CFLAGS = (
					"-fexceptions",
3852
3853
3854
3855
3856
3857
3858

3859
3860
3861
3862
3863
3864
3865
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = c11;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 2;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
				GCC_WARN_PEDANTIC = YES;

				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				OTHER_CFLAGS = (
					"-fexceptions",
					"-fconstant-string-class=OFConstantString",







>







3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = c11;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 2;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
				GCC_WARN_PEDANTIC = YES;
				GCC_WARN_SHADOW = YES;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				OTHER_CFLAGS = (
					"-fexceptions",
					"-fconstant-string-class=OFConstantString",

Modified configure.ac from [12f3d4bae6] to [e88e11e798].

1
2
3
4
5
6
7
8
AC_INIT(ObjFW, 0.9-dev, js@heap.zone)
BUILDSYS_INIT

AS_IF([test configure.ac -nt configure], [
	AC_MSG_ERROR([configure.ac is newer than configure! Run autoreconf!])
])

AC_CONFIG_SRCDIR(src)
|







1
2
3
4
5
6
7
8
AC_INIT(ObjFW, 0.90.1, js@heap.zone)
BUILDSYS_INIT

AS_IF([test configure.ac -nt configure], [
	AC_MSG_ERROR([configure.ac is newer than configure! Run autoreconf!])
])

AC_CONFIG_SRCDIR(src)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
	*-morphos*)
		AS_IF([test x"$with_ixemul" != x"yes"], [
			OBJCFLAGS="$OBJCFLAGS -noixemul"
			LDFLAGS="$LDFLAGS -noixemul"
			enable_files="yes"	# Required for reading ENV:

			AC_SUBST(NOIXEMUL, -noixemul)
			AC_SUBST(OBJFW_RT_MORPHOS_LIB, objfw-rt.library)
		])

		enable_shared="no"
		enable_threads="no"
		;;
	*-msdosdjgpp*)
		enable_shared="no"







<







21
22
23
24
25
26
27

28
29
30
31
32
33
34
	*-morphos*)
		AS_IF([test x"$with_ixemul" != x"yes"], [
			OBJCFLAGS="$OBJCFLAGS -noixemul"
			LDFLAGS="$LDFLAGS -noixemul"
			enable_files="yes"	# Required for reading ENV:

			AC_SUBST(NOIXEMUL, -noixemul)

		])

		enable_shared="no"
		enable_threads="no"
		;;
	*-msdosdjgpp*)
		enable_shared="no"
173
174
175
176
177
178
179


180
181
182
183
184
185
186
AX_CHECK_COMPILER_FLAGS(-fno-common, [OBJCFLAGS="$OBJCFLAGS -fno-common"])
AX_CHECK_COMPILER_FLAGS(-fno-constant-cfstrings, [
	OBJCFLAGS="$OBJCFLAGS -fno-constant-cfstrings"
	AC_SUBST(NO_CONST_CFSTRINGS, "-fno-constant-cfstrings")
])
AX_CHECK_COMPILER_FLAGS(-Wsign-compare -Werror,
	[OBJCFLAGS="$OBJCFLAGS -Wsign-compare"])


AX_CHECK_COMPILER_FLAGS(-Wshorten-64-to-32 -Werror,
	[OBJCFLAGS="$OBJCFLAGS -Wshorten-64-to-32"])
AX_CHECK_COMPILER_FLAGS(-Wsemicolon-before-method-body -Werror,
	[OBJCFLAGS="$OBJCFLAGS -Wsemicolon-before-method-body"])
AX_CHECK_COMPILER_FLAGS(-Wobjc-missing-property-synthesis -Werror,
	[OBJCFLAGS="$OBJCFLAGS -Wobjc-missing-property-synthesis"])
AX_CHECK_COMPILER_FLAGS(-Watomic-properties -Werror, [







>
>







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
AX_CHECK_COMPILER_FLAGS(-fno-common, [OBJCFLAGS="$OBJCFLAGS -fno-common"])
AX_CHECK_COMPILER_FLAGS(-fno-constant-cfstrings, [
	OBJCFLAGS="$OBJCFLAGS -fno-constant-cfstrings"
	AC_SUBST(NO_CONST_CFSTRINGS, "-fno-constant-cfstrings")
])
AX_CHECK_COMPILER_FLAGS(-Wsign-compare -Werror,
	[OBJCFLAGS="$OBJCFLAGS -Wsign-compare"])
AX_CHECK_COMPILER_FLAGS(-Wshadow -Werror,
	[OBJCFLAGS="$OBJCFLAGS -Wshadow"])
AX_CHECK_COMPILER_FLAGS(-Wshorten-64-to-32 -Werror,
	[OBJCFLAGS="$OBJCFLAGS -Wshorten-64-to-32"])
AX_CHECK_COMPILER_FLAGS(-Wsemicolon-before-method-body -Werror,
	[OBJCFLAGS="$OBJCFLAGS -Wsemicolon-before-method-body"])
AX_CHECK_COMPILER_FLAGS(-Wobjc-missing-property-synthesis -Werror,
	[OBJCFLAGS="$OBJCFLAGS -Wobjc-missing-property-synthesis"])
AX_CHECK_COMPILER_FLAGS(-Watomic-properties -Werror, [
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
	])
	AS_IF([test x"$enable_static" = x"yes" -o x"$enable_shared" = x"no"], [
		AC_SUBST(ENCODINGS_A, "encodings.a")
		AC_SUBST(ENCODINGS_ENCODINGS_A, "encodings/encodings.a")
	])
])

AC_CHECK_FUNCS(sigaction)

AC_CHECK_FUNCS(arc4random random, break)

AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl")
AC_CHECK_HEADERS_ONCE(dlfcn.h)
case "$host_os" in
	netbsd*)
		dnl dladdr exists on NetBSD, but it is completely broken.







<
<







654
655
656
657
658
659
660


661
662
663
664
665
666
667
	])
	AS_IF([test x"$enable_static" = x"yes" -o x"$enable_shared" = x"no"], [
		AC_SUBST(ENCODINGS_A, "encodings.a")
		AC_SUBST(ENCODINGS_ENCODINGS_A, "encodings/encodings.a")
	])
])



AC_CHECK_FUNCS(arc4random random, break)

AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl")
AC_CHECK_HEADERS_ONCE(dlfcn.h)
case "$host_os" in
	netbsd*)
		dnl dladdr exists on NetBSD, but it is completely broken.
1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
		AC_DEFINE(HAVE_EPOLL, 1, [Whether we have epoll])
		AC_SUBST(OFKERNELEVENTOBSERVER_EPOLL_M,
			"OFKernelEventObserver_epoll.m")
		break
	])

	AS_IF([test x"$with_wii" = x"yes"], [

		AC_SUBST(OFKERNELEVENTOBSERVER_POLL_M,
			"OFKernelEventObserver_poll.m")
	], [
		AC_CHECK_HEADERS(poll.h)
		AC_CHECK_FUNC(poll, [
			AC_DEFINE(HAVE_POLL, 1, [Whether we have poll()])
			AC_SUBST(OFKERNELEVENTOBSERVER_POLL_M,







>







1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
		AC_DEFINE(HAVE_EPOLL, 1, [Whether we have epoll])
		AC_SUBST(OFKERNELEVENTOBSERVER_EPOLL_M,
			"OFKernelEventObserver_epoll.m")
		break
	])

	AS_IF([test x"$with_wii" = x"yes"], [
		AC_DEFINE(HAVE_POLL, 1, [Whether we have poll()])
		AC_SUBST(OFKERNELEVENTOBSERVER_POLL_M,
			"OFKernelEventObserver_poll.m")
	], [
		AC_CHECK_HEADERS(poll.h)
		AC_CHECK_FUNC(poll, [
			AC_DEFINE(HAVE_POLL, 1, [Whether we have poll()])
			AC_SUBST(OFKERNELEVENTOBSERVER_POLL_M,
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
	*-*-msdosdjgpp*)
		have_processes="no"
		;;
	*)
		AC_HEADER_SYS_WAIT
		AC_CHECK_FUNCS(kill)

		AC_CHECK_FUNC(posix_spawnp, [
			AS_IF([test x"$ac_cv_func_kill" = x"yes"], [
				have_processes="yes"

				AC_CHECK_HEADERS(spawn.h)
			])
		], [
			AC_CHECK_FUNCS([vfork dup2 execvp _exit], [







|







1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
	*-*-msdosdjgpp*)
		have_processes="no"
		;;
	*)
		AC_HEADER_SYS_WAIT
		AC_CHECK_FUNCS(kill)

		AC_CHECK_FUNCS(posix_spawnp, [
			AS_IF([test x"$ac_cv_func_kill" = x"yes"], [
				have_processes="yes"

				AC_CHECK_HEADERS(spawn.h)
			])
		], [
			AC_CHECK_FUNCS([vfork dup2 execvp _exit], [

Modified extra.mk.in from [130d0ab22e] to [f18de84cc5].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@
OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@
# When changing: Be sure to also change these in the Xcode project!
OBJFW_LIB_MAJOR = 8
OBJFW_LIB_MINOR = 0
OBJFW_LIB_MAJOR_MINOR = ${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR}

OBJFW_RT_SHARED_LIB = @OBJFW_RT_SHARED_LIB@
OBJFW_RT_STATIC_LIB = @OBJFW_RT_STATIC_LIB@
OBJFW_RT_MORPHOS_LIB = @OBJFW_RT_MORPHOS_LIB@
OBJFW_RT_LIB_MAJOR = 0
OBJFW_RT_LIB_MINOR = 0
OBJFW_RT_LIB_MAJOR_MINOR = ${OBJFW_RT_LIB_MAJOR}.${OBJFW_RT_LIB_MINOR}

OBJFW_BRIDGE_SHARED_LIB = @OBJFW_BRIDGE_SHARED_LIB@
OBJFW_BRIDGE_STATIC_LIB = @OBJFW_BRIDGE_STATIC_LIB@





|




<







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@
OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@
# When changing: Be sure to also change these in the Xcode project!
OBJFW_LIB_MAJOR = 8
OBJFW_LIB_MINOR = 1
OBJFW_LIB_MAJOR_MINOR = ${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR}

OBJFW_RT_SHARED_LIB = @OBJFW_RT_SHARED_LIB@
OBJFW_RT_STATIC_LIB = @OBJFW_RT_STATIC_LIB@

OBJFW_RT_LIB_MAJOR = 0
OBJFW_RT_LIB_MINOR = 0
OBJFW_RT_LIB_MAJOR_MINOR = ${OBJFW_RT_LIB_MAJOR}.${OBJFW_RT_LIB_MINOR}

OBJFW_BRIDGE_SHARED_LIB = @OBJFW_BRIDGE_SHARED_LIB@
OBJFW_BRIDGE_STATIC_LIB = @OBJFW_BRIDGE_STATIC_LIB@

Modified src/OFApplication.h from [627b4181f1] to [e7e5df2d5d].

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
{
	OFString *_programName;
	OFArray OF_GENERIC(OFString *) *_arguments;
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_environment;
	int *_argc;
	char ***_argv;
@public
	id <OFApplicationDelegate> _delegate;
	void (*_SIGINTHandler)(id, SEL);
#ifndef OF_WINDOWS
	void (*_SIGHUPHandler)(id, SEL);
	void (*_SIGUSR1Handler)(id, SEL);
	void (*_SIGUSR2Handler)(id, SEL);
#endif
}

/*!
 * The name of the program (argv[0]).
 */
@property (readonly, nonatomic) OFString *programName;







|
|

|
|
|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
{
	OFString *_programName;
	OFArray OF_GENERIC(OFString *) *_arguments;
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_environment;
	int *_argc;
	char ***_argv;
@public
	id <OFApplicationDelegate> _Nullable _delegate;
	void (*_Nullable _SIGINTHandler)(id, SEL);
#ifndef OF_WINDOWS
	void (*_Nullable _SIGHUPHandler)(id, SEL);
	void (*_Nullable _SIGUSR1Handler)(id, SEL);
	void (*_Nullable _SIGUSR2Handler)(id, SEL);
#endif
}

/*!
 * The name of the program (argv[0]).
 */
@property (readonly, nonatomic) OFString *programName;
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    OFDictionary OF_GENERIC(OFString *, OFString *) *environment;

/*!
 * @brief Returns the only OFApplication instance in the application.
 *
 * @return The only OFApplication instance in the application
 */
+ (OFApplication *)sharedApplication;

/*!
 * @brief Returns the name of the program (argv[0]).
 *
 * @return The name of the program (argv[0])
 */
+ (OFString *)programName;

/*!
 * @brief Returns the arguments passed to the application.
 *
 * @return The arguments passed to the application
 */
+ (OFArray OF_GENERIC(OFString *) *)arguments;

/*!
 * @brief Returns the environment of the application.
 *
 * @return The environment of the application
 */
+ (OFDictionary OF_GENERIC(OFString *, OFString *) *)environment;

/*!
 * @brief Terminates the application with the EXIT_SUCCESS status.
 */
+ (void)terminate OF_NO_RETURN;

/*!







|






|






|






|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    OFDictionary OF_GENERIC(OFString *, OFString *) *environment;

/*!
 * @brief Returns the only OFApplication instance in the application.
 *
 * @return The only OFApplication instance in the application
 */
+ (nullable OFApplication *)sharedApplication;

/*!
 * @brief Returns the name of the program (argv[0]).
 *
 * @return The name of the program (argv[0])
 */
+ (nullable OFString *)programName;

/*!
 * @brief Returns the arguments passed to the application.
 *
 * @return The arguments passed to the application
 */
+ (nullable OFArray OF_GENERIC(OFString *) *)arguments;

/*!
 * @brief Returns the environment of the application.
 *
 * @return The environment of the application
 */
+ (nullable OFDictionary OF_GENERIC(OFString *, OFString *) *)environment;

/*!
 * @brief Terminates the application with the EXIT_SUCCESS status.
 */
+ (void)terminate OF_NO_RETURN;

/*!

Modified src/OFApplication.m from [c9d4f7d315] to [f12746971d].

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

#ifdef OF_NINTENDO_DS
# define asm __asm__
# include <nds.h>
# undef asm
#endif

#ifdef HAVE_SIGACTION
# ifndef SA_RESTART
#  define SA_RESTART 0
# endif
#endif

@interface OFApplication ()
- (instancetype)of_init OF_METHOD_FAMILY(init);
- (void)of_setArgumentCount: (int *)argc
	  andArgumentValues: (char **[])argv;
#ifdef OF_WINDOWS
- (void)of_setArgumentCount: (int)argc
      andWideArgumentValues: (wchar_t *[])argv;







<
<
<
<
<
<







67
68
69
70
71
72
73






74
75
76
77
78
79
80

#ifdef OF_NINTENDO_DS
# define asm __asm__
# include <nds.h>
# undef asm
#endif







@interface OFApplication ()
- (instancetype)of_init OF_METHOD_FAMILY(init);
- (void)of_setArgumentCount: (int *)argc
	  andArgumentValues: (char **[])argv;
#ifdef OF_WINDOWS
- (void)of_setArgumentCount: (int)argc
      andWideArgumentValues: (wchar_t *[])argv;
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536

537
538

539
540
541
542
543
544
545
- (id <OFApplicationDelegate>)delegate
{
	return _delegate;
}

- (void)setDelegate: (id <OFApplicationDelegate>)delegate
{
#ifdef HAVE_SIGACTION
	struct sigaction sa = { .sa_flags = SA_RESTART };
	sigemptyset(&sa.sa_mask);

# define REGISTER_SIGNAL(sig)						\
	if ([delegate respondsToSelector:				\
	    @selector(applicationDidReceive##sig)]) {			\
		_##sig##Handler = (void (*)(id, SEL))[(id)delegate	\
		    methodForSelector:					\
		    @selector(applicationDidReceive##sig)];		\
									\
		sa.sa_handler = handle##sig;				\
	} else								\
		sa.sa_handler = SIG_DFL;				\
									\
	OF_ENSURE(sigaction(sig, &sa, NULL) == 0);
#else
# define REGISTER_SIGNAL(sig)						\
	if ([delegate respondsToSelector:				\
	    @selector(applicationDidReceive##sig)]) {			\
		_##sig##Handler = (void (*)(id, SEL))[(id)delegate	\
		    methodForSelector:					\
		    @selector(applicationDidReceive##sig)];		\
		signal(sig, handle##sig);				\
	} else								\

		signal(sig, (void (*)(int))SIG_DFL);
#endif


	_delegate = delegate;

	REGISTER_SIGNAL(SIGINT)
#ifdef SIGHUP
	REGISTER_SIGNAL(SIGHUP)
#endif







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<






|
>
|
<
>







499
500
501
502
503
504
505




506













507
508
509
510
511
512
513
514
515

516
517
518
519
520
521
522
523
- (id <OFApplicationDelegate>)delegate
{
	return _delegate;
}

- (void)setDelegate: (id <OFApplicationDelegate>)delegate
{




#define REGISTER_SIGNAL(sig)						\













	if ([delegate respondsToSelector:				\
	    @selector(applicationDidReceive##sig)]) {			\
		_##sig##Handler = (void (*)(id, SEL))[(id)delegate	\
		    methodForSelector:					\
		    @selector(applicationDidReceive##sig)];		\
		signal(sig, handle##sig);				\
	} else {							\
		_##sig##Handler = NULL;					\
		signal(sig, (void (*)(int))SIG_DFL);			\

	}

	_delegate = delegate;

	REGISTER_SIGNAL(SIGINT)
#ifdef SIGHUP
	REGISTER_SIGNAL(SIGHUP)
#endif

Modified src/OFArray.h from [768648064e] to [9cbd05d142].

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 * each object.
 *
 * @note A @ref OFNull value is translated to nil!
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString *)key;

/*!
 * @brief Copies the objects at the specified range to the specified buffer.
 *
 * @param buffer The buffer to copy the objects to
 * @param range The range to copy







|







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 * each object.
 *
 * @note A @ref OFNull value is translated to nil!
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (id)value
	  forKey: (OFString *)key;

/*!
 * @brief Copies the objects at the specified range to the specified buffer.
 *
 * @param buffer The buffer to copy the objects to
 * @param range The range to copy
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/*!
 * @brief Checks whether the array contains an object equal to the specified
 *	  object.
 *
 * @param object The object which is checked for being in the array
 * @return A boolean whether the array contains the specified object
 */
- (bool)containsObject: (nullable ObjectType)object;

/*!
 * @brief Checks whether the array contains an object with the specified
 *	  address.
 *
 * @param object The object which is checked for being in the array
 * @return A boolean whether the array contains an object with the specified
 *	   address
 */
- (bool)containsObjectIdenticalTo: (nullable ObjectType)object;

/*!
 * @brief Returns the first object of the array or `nil`.
 *
 * @warning The returned object is *not* retained and autoreleased for
 *	    performance reasons!
 *







|









|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/*!
 * @brief Checks whether the array contains an object equal to the specified
 *	  object.
 *
 * @param object The object which is checked for being in the array
 * @return A boolean whether the array contains the specified object
 */
- (bool)containsObject: (ObjectType)object;

/*!
 * @brief Checks whether the array contains an object with the specified
 *	  address.
 *
 * @param object The object which is checked for being in the array
 * @return A boolean whether the array contains an object with the specified
 *	   address
 */
- (bool)containsObjectIdenticalTo: (ObjectType)object;

/*!
 * @brief Returns the first object of the array or `nil`.
 *
 * @warning The returned object is *not* retained and autoreleased for
 *	    performance reasons!
 *
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# undef ObjectType
#endif
@end

@interface OFArrayEnumerator: OFEnumerator
{
	OFArray	      *_array;
	size_t	      _count;
	unsigned long _mutations;
	unsigned long *_mutationsPtr;
	size_t	      _position;
}

- initWithArray: (OFArray *)data
   mutationsPtr: (unsigned long *_Nullable)mutationsPtr;
@end

OF_ASSUME_NONNULL_END

#import "OFMutableArray.h"

#if !defined(NSINTEGER_DEFINED) && !__has_feature(modules)
/* Required for array literals to work */
@compatibility_alias NSArray OFArray;
#endif







|
|

|
|



|










481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# undef ObjectType
#endif
@end

@interface OFArrayEnumerator: OFEnumerator
{
	OFArray	*_array;
	size_t _count;
	unsigned long _mutations;
	unsigned long *_Nullable _mutationsPtr;
	size_t _position;
}

- initWithArray: (OFArray *)data
   mutationsPtr: (nullable unsigned long *)mutationsPtr;
@end

OF_ASSUME_NONNULL_END

#import "OFMutableArray.h"

#if !defined(NSINTEGER_DEFINED) && !__has_feature(modules)
/* Required for array literals to work */
@compatibility_alias NSArray OFArray;
#endif

Modified src/OFArray.m from [15022d3186] to [ffbda05782].

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
- (id)objectAtIndexedSubscript: (size_t)index
{
	return [self objectAtIndex: index];
}

- (id)valueForKey: (OFString *)key
{
	OFMutableArray *ret;

	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();
		id ret;

		key = [key substringWithRange: of_range(1, [key length] - 1)];
		ret = [[super valueForKey: key] retain];

		objc_autoreleasePoolPop(pool);

		return [ret autorelease];







|



<







271
272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
- (id)objectAtIndexedSubscript: (size_t)index
{
	return [self objectAtIndex: index];
}

- (id)valueForKey: (OFString *)key
{
	id ret;

	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();


		key = [key substringWithRange: of_range(1, [key length] - 1)];
		ret = [[super valueForKey: key] retain];

		objc_autoreleasePoolPop(pool);

		return [ret autorelease];
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
		[super setValue: value
			 forKey: key];

		objc_autoreleasePoolPop(pool);
		return;
	}

	if (value == [OFNull null])
		value = nil;

	for (id object in self)
		[object setValue: value
			  forKey: key];
}

- (size_t)indexOfObject: (id)object
{







<
<
<







314
315
316
317
318
319
320



321
322
323
324
325
326
327
		[super setValue: value
			 forKey: key];

		objc_autoreleasePoolPop(pool);
		return;
	}




	for (id object in self)
		[object setValue: value
			  forKey: key];
}

- (size_t)indexOfObject: (id)object
{
448
449
450
451
452
453
454

455

456






457
458
459
460
461
462
463
464
465



466
467
468
469
470
471
472
473
474
475
476
477
478





479
480
481
482
483
484
485
486
487
488
489
490
491
492
	OFMutableString *ret;

	if (separator == nil)
		@throw [OFInvalidArgumentException exception];

	if ([self count] == 0)
		return @"";

	if ([self count] == 1)

		return [[self firstObject] performSelector: selector];







	ret = [OFMutableString string];

	if (options & OF_ARRAY_SKIP_EMPTY) {
		for (id object in self) {
			void *pool = objc_autoreleasePoolPush();
			OFString *component =
			    [object performSelector: selector];




			if ([component length] > 0) {
				if ([ret length] > 0)
					[ret appendString: separator];
				[ret appendString: component];
			}

			objc_autoreleasePoolPop(pool);
		}
	} else {
		bool first = true;

		for (id object in self) {
			void *pool = objc_autoreleasePoolPush();






			if OF_UNLIKELY (first)
				first = false;
			else
				[ret appendString: separator];

			[ret appendString: [object performSelector: selector]];

			objc_autoreleasePoolPop(pool);
		}
	}

	[ret makeImmutable];








>
|
>
|
>
>
>
>
>
>









>
>
>













>
>
>
>
>






|







444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
	OFMutableString *ret;

	if (separator == nil)
		@throw [OFInvalidArgumentException exception];

	if ([self count] == 0)
		return @"";

	if ([self count] == 1) {
		OFString *component =
		    [[self firstObject] performSelector: selector];

		if (component == nil)
			@throw [OFInvalidArgumentException exception];

		return component;
	}

	ret = [OFMutableString string];

	if (options & OF_ARRAY_SKIP_EMPTY) {
		for (id object in self) {
			void *pool = objc_autoreleasePoolPush();
			OFString *component =
			    [object performSelector: selector];

			if (component == nil)
				@throw [OFInvalidArgumentException exception];

			if ([component length] > 0) {
				if ([ret length] > 0)
					[ret appendString: separator];
				[ret appendString: component];
			}

			objc_autoreleasePoolPop(pool);
		}
	} else {
		bool first = true;

		for (id object in self) {
			void *pool = objc_autoreleasePoolPush();
			OFString *component =
			    [object performSelector: selector];

			if (component == nil)
				@throw [OFInvalidArgumentException exception];

			if OF_UNLIKELY (first)
				first = false;
			else
				[ret appendString: separator];

			[ret appendString: component];

			objc_autoreleasePoolPop(pool);
		}
	}

	[ret makeImmutable];

672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
		uint8_t type = 0xDC;
		uint16_t tmp = OF_BSWAP16_IF_LE((uint16_t)count);

		[data addItem: &type];
		[data addItems: &tmp
			 count: sizeof(tmp)];
	} else if (count <= UINT32_MAX) {
		uint8_t type = 0xDC;
		uint32_t tmp = OF_BSWAP32_IF_LE((uint32_t)count);

		[data addItem: &type];
		[data addItems: &tmp
			 count: sizeof(tmp)];
	} else
		@throw [OFOutOfRangeException exception];







|







684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
		uint8_t type = 0xDC;
		uint16_t tmp = OF_BSWAP16_IF_LE((uint16_t)count);

		[data addItem: &type];
		[data addItems: &tmp
			 count: sizeof(tmp)];
	} else if (count <= UINT32_MAX) {
		uint8_t type = 0xDD;
		uint32_t tmp = OF_BSWAP32_IF_LE((uint32_t)count);

		[data addItem: &type];
		[data addItems: &tmp
			 count: sizeof(tmp)];
	} else
		@throw [OFOutOfRangeException exception];
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
	for (id object in self)
		[object performSelector: selector];
}

- (void)makeObjectsPerformSelector: (SEL)selector
			withObject: (id)object
{
	for (id object in self)
		[object performSelector: selector
			     withObject: object];
}

- (OFArray *)sortedArray
{
	OFMutableArray *new = [[self mutableCopy] autorelease];

	[new sort];







|
|
|







727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
	for (id object in self)
		[object performSelector: selector];
}

- (void)makeObjectsPerformSelector: (SEL)selector
			withObject: (id)object
{
	for (id objectIter in self)
		[objectIter performSelector: selector
				 withObject: object];
}

- (OFArray *)sortedArray
{
	OFMutableArray *new = [[self mutableCopy] autorelease];

	[new sort];

Modified src/OFCollection.h from [443478d52e] to [835760a641].

34
35
36
37
38
39
40
41
42
43
44
/*!
 * @brief Checks whether the collection contains an object equal to the
 *	  specified object.
 *
 * @param object The object which is checked for being in the collection
 * @return A boolean whether the collection contains the specified object
 */
- (bool)containsObject: (nullable id)object;
@end

OF_ASSUME_NONNULL_END







|



34
35
36
37
38
39
40
41
42
43
44
/*!
 * @brief Checks whether the collection contains an object equal to the
 *	  specified object.
 *
 * @param object The object which is checked for being in the collection
 * @return A boolean whether the collection contains the specified object
 */
- (bool)containsObject: (id)object;
@end

OF_ASSUME_NONNULL_END

Modified src/OFConstantString.m from [a025049426] to [58b7594810].

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
@implementation OFConstantString
+ (void)load
{
#if defined(OF_APPLE_RUNTIME) && !defined(__OBJC2__)
	/*
	 * objc_setFutureClass suddenly stopped working as OFConstantString
	 * became more complex. So the only solution is to make
	 * _OFConstantStringClassRerence the actual class, but there is no
	 * objc_initializeClassPair in 10.5. However, objc_allocateClassPair
	 * does not register the new class with the subclass in the ObjC1
	 * runtime like the ObjC2 runtime does, so this workaround should be
	 * fine.
	 */
	Class class;








|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
@implementation OFConstantString
+ (void)load
{
#if defined(OF_APPLE_RUNTIME) && !defined(__OBJC2__)
	/*
	 * objc_setFutureClass suddenly stopped working as OFConstantString
	 * became more complex. So the only solution is to make
	 * _OFConstantStringClassReference the actual class, but there is no
	 * objc_initializeClassPair in 10.5. However, objc_allocateClassPair
	 * does not register the new class with the subclass in the ObjC1
	 * runtime like the ObjC2 runtime does, so this workaround should be
	 * fine.
	 */
	Class class;

Modified src/OFData.h from [ef14e3ba64] to [9086a3be08].

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 *
 * For security reasons, serialization and deserialization is only implemented
 * for OFData with item size 1.
 */
@interface OFData: OFObject <OFCopying, OFMutableCopying, OFComparing,
    OFSerialization, OFMessagePackRepresentation>
{
	char *_items;
	size_t _count, _itemSize;
	bool _freeWhenDone;
}

/*!
 * The size of a single item in the OFData in bytes.
 */







|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 *
 * For security reasons, serialization and deserialization is only implemented
 * for OFData with item size 1.
 */
@interface OFData: OFObject <OFCopying, OFMutableCopying, OFComparing,
    OFSerialization, OFMessagePackRepresentation>
{
	unsigned char *_items;
	size_t _count, _itemSize;
	bool _freeWhenDone;
}

/*!
 * The size of a single item in the OFData in bytes.
 */

Modified src/OFData.m from [ab1e932258] to [945c020d4d].

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = (char *)items;
		_itemSize = itemSize;
		_count = count;
		_freeWhenDone = freeWhenDone;
	} @catch (id e) {
		[self release];
		@throw e;
	}







|







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = (unsigned char *)items;
		_itemSize = itemSize;
		_count = count;
		_freeWhenDone = freeWhenDone;
	} @catch (id e) {
		[self release];
		@throw e;
	}

Modified src/OFDate.h from [7c2a95ab3f] to [29c60ccceb].

184
185
186
187
188
189
190







191
192
193
194
195
196
197
/*!
 * @brief Returns the minute of the date.
 *
 * @return The minute of the date
 */
- (uint8_t)minute;








/*!
 * @brief Returns the hour of the date.
 *
 * @return The hour of the date
 */
- (uint8_t)hour;








>
>
>
>
>
>
>







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*!
 * @brief Returns the minute of the date.
 *
 * @return The minute of the date
 */
- (uint8_t)minute;

/*!
 * @brief Returns the minute of the date in local time.
 *
 * @return The minute of the date in local time
 */
- (uint8_t)localMinute;

/*!
 * @brief Returns the hour of the date.
 *
 * @return The hour of the date
 */
- (uint8_t)hour;

296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
 * @brief Returns the earlier of the two dates.
 *
 * If the argument is `nil`, it returns the receiver.
 *
 * @param otherDate Another date
 * @return The earlier date of the two dates
 */
- (OFDate *)earlierDate: (OFDate *)otherDate;

/*!
 * @brief Returns the later of the two dates.
 *
 * If the argument is `nil`, it returns the receiver.
 *
 * @param otherDate Another date
 * @return The later date of the two dates
 */
- (OFDate *)laterDate: (OFDate *)otherDate;

/*!
 * @brief Returns the seconds since 1970-01-01T00:00:00Z.
 *
 * @return The seconds since 1970-01-01T00:00:00Z
 */
- (of_time_interval_t)timeIntervalSince1970;







|









|







303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
 * @brief Returns the earlier of the two dates.
 *
 * If the argument is `nil`, it returns the receiver.
 *
 * @param otherDate Another date
 * @return The earlier date of the two dates
 */
- (OFDate *)earlierDate: (nullable OFDate *)otherDate;

/*!
 * @brief Returns the later of the two dates.
 *
 * If the argument is `nil`, it returns the receiver.
 *
 * @param otherDate Another date
 * @return The later date of the two dates
 */
- (OFDate *)laterDate: (nullable OFDate *)otherDate;

/*!
 * @brief Returns the seconds since 1970-01-01T00:00:00Z.
 *
 * @return The seconds since 1970-01-01T00:00:00Z
 */
- (of_time_interval_t)timeIntervalSince1970;

Modified src/OFDate.m from [388aebd154] to [618922b043].

449
450
451
452
453
454
455





456
457
458
459
460
461
462
	GMTIME_RET(tm_sec)
}

- (uint8_t)minute
{
	GMTIME_RET(tm_min)
}






- (uint8_t)hour
{
	GMTIME_RET(tm_hour)
}

- (uint8_t)localHour







>
>
>
>
>







449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
	GMTIME_RET(tm_sec)
}

- (uint8_t)minute
{
	GMTIME_RET(tm_min)
}

- (uint8_t)localMinute
{
	LOCALTIME_RET(tm_min)
}

- (uint8_t)hour
{
	GMTIME_RET(tm_hour)
}

- (uint8_t)localHour

Modified src/OFDictionary.h from [cf57ae790d] to [085a75867d].

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
 * If the key does not start with an `@`, this is equivalent to
 * @ref setObject:forKey:. In this case, if the dictionary is immutable, an
 * @ref OFUndefinedKeyException is thrown.
 *
 * @param key The key to set
 * @param value The value to set the key to
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString *)key;

/*!
 * @brief Checks whether the dictionary contains an object equal to the
 *	  specified object.
 *
 * @param object The object which is checked for being in the dictionary
 * @return A boolean whether the dictionary contains the specified object
 */
- (bool)containsObject: (nullable ObjectType)object;

/*!
 * @brief Checks whether the dictionary contains an object with the specified
 *	  address.
 *
 * @param object The object which is checked for being in the dictionary
 * @return A boolean whether the dictionary contains an object with the
 *	   specified address
 */
- (bool)containsObjectIdenticalTo: (nullable ObjectType)object;

/*!
 * @brief Returns an array of all keys.
 *
 * @return An array of all keys
 */
- (OFArray OF_GENERIC(KeyType) *)allKeys;







|









|









|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
 * If the key does not start with an `@`, this is equivalent to
 * @ref setObject:forKey:. In this case, if the dictionary is immutable, an
 * @ref OFUndefinedKeyException is thrown.
 *
 * @param key The key to set
 * @param value The value to set the key to
 */
- (void)setValue: (id)value
	  forKey: (OFString *)key;

/*!
 * @brief Checks whether the dictionary contains an object equal to the
 *	  specified object.
 *
 * @param object The object which is checked for being in the dictionary
 * @return A boolean whether the dictionary contains the specified object
 */
- (bool)containsObject: (ObjectType)object;

/*!
 * @brief Checks whether the dictionary contains an object with the specified
 *	  address.
 *
 * @param object The object which is checked for being in the dictionary
 * @return A boolean whether the dictionary contains an object with the
 *	   specified address
 */
- (bool)containsObjectIdenticalTo: (ObjectType)object;

/*!
 * @brief Returns an array of all keys.
 *
 * @return An array of all keys
 */
- (OFArray OF_GENERIC(KeyType) *)allKeys;

Modified src/OFFile.m from [afef5a8ffe] to [44dc0ec6b9].

130
131
132
133
134
135
136


137
138
139
140




141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
static int
parseMode(const char *mode, bool *append)
{
	*append = false;

	if (strcmp(mode, "r") == 0)
		return MODE_OLDFILE;


	if (strcmp(mode, "w") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "wx") == 0)
		return MODE_NEWFILE;




	if (strcmp(mode, "a") == 0) {
		*append = true;
		return MODE_READWRITE;
	}
	if (strcmp(mode, "rb") == 0)
		return MODE_OLDFILE;
	if (strcmp(mode, "wb") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "wbx") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "ab") == 0) {
		*append = true;
		return MODE_READWRITE;
	}
	if (strcmp(mode, "r+") == 0)
		return MODE_OLDFILE;
	if (strcmp(mode, "w+") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "a+") == 0) {
		*append = true;
		return MODE_READWRITE;
	}
	if (strcmp(mode, "r+b") == 0 || strcmp(mode, "rb+") == 0)
		return MODE_OLDFILE;
	if (strcmp(mode, "w+b") == 0 || strcmp(mode, "wb+") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "w+bx") == 0 || strcmp(mode, "wb+x") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "ab+") == 0 || strcmp(mode, "a+b") == 0) {
		*append = true;
		return MODE_READWRITE;
	}

	return -1;
}
#endif








>
>




>
>
>
>




<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150














151
152










153
154
155
156
157
158
159
static int
parseMode(const char *mode, bool *append)
{
	*append = false;

	if (strcmp(mode, "r") == 0)
		return MODE_OLDFILE;
	if (strcmp(mode, "r+") == 0)
		return MODE_OLDFILE;
	if (strcmp(mode, "w") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "wx") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "w+") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "w+x") == 0)
		return MODE_NEWFILE;
	if (strcmp(mode, "a") == 0) {
		*append = true;
		return MODE_READWRITE;
	}














	if (strcmp(mode, "a+") == 0) {
		*append = true;










		return MODE_READWRITE;
	}

	return -1;
}
#endif

Modified src/OFFileManager.m from [7bb3d63d81] to [f7096a9a7b].

569
570
571
572
573
574
575

576
577
578
579
580
581
582
				    exceptionWithObject: self
					requestedLength: 0
						  errNo: errno];

			if (dirent == NULL)
				break;
# else

			if ((dirent = readdir(dir)) == NULL) {
				if (errno == 0)
					break;
				else
					@throw [OFReadFailedException
					    exceptionWithObject: self
						requestedLength: 0







>







569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
				    exceptionWithObject: self
					requestedLength: 0
						  errNo: errno];

			if (dirent == NULL)
				break;
# else
			errno = 0;
			if ((dirent = readdir(dir)) == NULL) {
				if (errno == 0)
					break;
				else
					@throw [OFReadFailedException
					    exceptionWithObject: self
						requestedLength: 0

Modified src/OFGZIPStream.h from [9ece715a6e] to [5bd0cee2bc].

17
18
19
20
21
22
23






24
25
26
27
28
29
30
31
32
33
34
#import "OFStream.h"
#import "OFDate.h"

@class OFInflateStream;

OF_ASSUME_NONNULL_BEGIN







@interface OFGZIPStream: OFStream
{
	OFStream *_stream;
	OFInflateStream *_inflateStream;
	enum of_gzip_stream_state {
		OF_GZIP_STREAM_ID1,
		OF_GZIP_STREAM_ID2,
		OF_GZIP_STREAM_COMPRESSION_METHOD,
		OF_GZIP_STREAM_FLAGS,
		OF_GZIP_STREAM_MODIFICATION_TIME,
		OF_GZIP_STREAM_EXTRA_FLAGS,







>
>
>
>
>
>



|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#import "OFStream.h"
#import "OFDate.h"

@class OFInflateStream;

OF_ASSUME_NONNULL_BEGIN

/*!
 * @class OFGZIPStream OFGZIPStream.h ObjFW/OFGZIPStream.h
 *
 * @brief A class that handles GZIP compression and decompression transparently
 *	  for an underlying stream.
 */
@interface OFGZIPStream: OFStream
{
	OFStream *_stream;
	OFInflateStream *_Nullable _inflateStream;
	enum of_gzip_stream_state {
		OF_GZIP_STREAM_ID1,
		OF_GZIP_STREAM_ID2,
		OF_GZIP_STREAM_COMPRESSION_METHOD,
		OF_GZIP_STREAM_FLAGS,
		OF_GZIP_STREAM_MODIFICATION_TIME,
		OF_GZIP_STREAM_EXTRA_FLAGS,
65
66
67
68
69
70
71
72
73
74
75
76






77

78








79
80
81
82
		OF_GZIP_STREAM_OS_NTFS	       =  11,
		OF_GZIP_STREAM_OS_QDOS	       =  12,
		OF_GZIP_STREAM_OS_ACORN_RISCOS =  13,
		OF_GZIP_STREAM_OS_UNKNOWN      = 255
	} _OS;
	size_t _bytesRead;
	uint8_t _buffer[4];
	OFDate *_modificationDate;
	uint16_t _extraLength;
	uint32_t _CRC32, _uncompressedSize;
}







+ (instancetype)streamWithStream: (OFStream *)stream;

- init OF_UNAVAILABLE;








- initWithStream: (OFStream *)stream OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END







|




>
>
>
>
>
>

>

>
>
>
>
>
>
>
>




71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
		OF_GZIP_STREAM_OS_NTFS	       =  11,
		OF_GZIP_STREAM_OS_QDOS	       =  12,
		OF_GZIP_STREAM_OS_ACORN_RISCOS =  13,
		OF_GZIP_STREAM_OS_UNKNOWN      = 255
	} _OS;
	size_t _bytesRead;
	uint8_t _buffer[4];
	OFDate *_Nullable _modificationDate;
	uint16_t _extraLength;
	uint32_t _CRC32, _uncompressedSize;
}

/*!
 * @brief Creates a new OFGZIPStream with the specified underlying stream.
 *
 * @param stream The underlying stream for the OFGZIPStream
 * @return A new, autoreleased OFGZIPStream
 */
+ (instancetype)streamWithStream: (OFStream *)stream;

- init OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated OFGZIPStream with the specified
 *	  underlying stream.
 *
 * @param stream The underlying stream for the OFGZIPStream
 * @return An initialized OFGZIPStream
 */
- initWithStream: (OFStream *)stream OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/OFHMAC.h from [78bbd3d482] to [10fea24a9c].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * @class OFHMAC OFHMAC.h ObjFW/OFHMAC.h
 *
 * @brief A class which provides methods to calculate an HMAC.
 */
@interface OFHMAC: OFObject
{
	Class <OFCryptoHash> _hashClass;
	id <OFCryptoHash> _outerHash, _innerHash;
	id <OFCryptoHash> _outerHashCopy, _innerHashCopy;
	bool _calculated;
}

/*! The class for the cryptographic hash used by the HMAC. */
@property (readonly, nonatomic) Class <OFCryptoHash> hashClass;

/*!







|
|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * @class OFHMAC OFHMAC.h ObjFW/OFHMAC.h
 *
 * @brief A class which provides methods to calculate an HMAC.
 */
@interface OFHMAC: OFObject
{
	Class <OFCryptoHash> _hashClass;
	id <OFCryptoHash> _Nullable _outerHash, _innerHash;
	id <OFCryptoHash> _Nullable _outerHashCopy, _innerHashCopy;
	bool _calculated;
}

/*! The class for the cryptographic hash used by the HMAC. */
@property (readonly, nonatomic) Class <OFCryptoHash> hashClass;

/*!

Modified src/OFHTTPClient.h from [a366523288] to [cd3656efe4].

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*!
 * @class OFHTTPClient OFHTTPClient.h ObjFW/OFHTTPClient.h
 *
 * @brief A class for performing HTTP requests.
 */
@interface OFHTTPClient: OFObject
{
	id <OFHTTPClientDelegate> _delegate;
	bool _insecureRedirectsAllowed;
	OFTCPSocket *_socket;
	OFURL *_lastURL;
	bool _lastWasHEAD;
	OFHTTPResponse *_lastResponse;
}

/*!
 * The delegate of the HTTP request.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, assign)
    id <OFHTTPClientDelegate> delegate;







|

|
|

|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*!
 * @class OFHTTPClient OFHTTPClient.h ObjFW/OFHTTPClient.h
 *
 * @brief A class for performing HTTP requests.
 */
@interface OFHTTPClient: OFObject
{
	id <OFHTTPClientDelegate> _Nullable _delegate;
	bool _insecureRedirectsAllowed;
	OFTCPSocket *_Nullable _socket;
	OFURL *_Nullable _lastURL;
	bool _lastWasHEAD;
	OFHTTPResponse *_Nullable _lastResponse;
}

/*!
 * The delegate of the HTTP request.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, assign)
    id <OFHTTPClientDelegate> delegate;

Modified src/OFHTTPCookie.h from [b3a1f16ba1] to [00698eed19].

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 * @class OFHTTPCookie OFHTTPCookie.h ObjFW/OFHTTPCookie.h
 *
 * @brief A class for storing and manipulating HTTP cookies.
 */
@interface OFHTTPCookie: OFObject <OFCopying>
{
	OFString *_name, *_value, *_domain, *_path;
	OFDate *_expires;
	bool _secure, _HTTPOnly;
	OFMutableArray OF_GENERIC(OFString *) *_extensions;
}

/*!
 * The name of the cookie.
 */







|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 * @class OFHTTPCookie OFHTTPCookie.h ObjFW/OFHTTPCookie.h
 *
 * @brief A class for storing and manipulating HTTP cookies.
 */
@interface OFHTTPCookie: OFObject <OFCopying>
{
	OFString *_name, *_value, *_domain, *_path;
	OFDate *_Nullable _expires;
	bool _secure, _HTTPOnly;
	OFMutableArray OF_GENERIC(OFString *) *_extensions;
}

/*!
 * The name of the cookie.
 */

Modified src/OFHTTPRequest.h from [c4ecec1316] to [c06e523cb0].

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 * @brief A class for storing HTTP requests.
 */
@interface OFHTTPRequest: OFObject <OFCopying>
{
	OFURL *_URL;
	of_http_request_method_t _method;
	of_http_request_protocol_version_t _protocolVersion;
	OFDictionary OF_GENERIC(OFString *, OFString *) *_headers;
	OFData *_body;
	OFString *_remoteAddress;
}

/*!
 * The URL of the HTTP request.
 */
@property (nonatomic, copy) OFURL *URL;








|
|
|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 * @brief A class for storing HTTP requests.
 */
@interface OFHTTPRequest: OFObject <OFCopying>
{
	OFURL *_URL;
	of_http_request_method_t _method;
	of_http_request_protocol_version_t _protocolVersion;
	OFDictionary OF_GENERIC(OFString *, OFString *) *_Nullable _headers;
	OFData *_Nullable _body;
	OFString *_Nullable _remoteAddress;
}

/*!
 * The URL of the HTTP request.
 */
@property (nonatomic, copy) OFURL *URL;

Modified src/OFHTTPResponse.h from [96ba448907] to [50360976c1].

38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
 * The status code of the reply to the HTTP request.
 */
@property (nonatomic) short statusCode;

/*!
 * The headers of the reply to the HTTP request.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, copy)
    OFDictionary OF_GENERIC(OFString *, OFString *) *headers;


/*!
 * @brief Sets the protocol version of the HTTP request reply.
 *
 * @param protocolVersion The protocol version of the HTTP request reply
 */
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion;







<
|
>







38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
 * The status code of the reply to the HTTP request.
 */
@property (nonatomic) short statusCode;

/*!
 * The headers of the reply to the HTTP request.
 */

@property (copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *)
    *headers;

/*!
 * @brief Sets the protocol version of the HTTP request reply.
 *
 * @param protocolVersion The protocol version of the HTTP request reply
 */
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion;

Modified src/OFHTTPResponse.m from [a696a64757] to [78fcbe257c].

138
139
140
141
142
143
144

145
146





147
148
149
150
151
152
153
@implementation OFHTTPResponse
@synthesize statusCode = _statusCode, headers = _headers;

- init
{
	self = [super init];


	_protocolVersion.major = 1;
	_protocolVersion.minor = 1;






	return self;
}

- (void)dealloc
{
	[_headers release];







>
|
|
>
>
>
>
>







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
@implementation OFHTTPResponse
@synthesize statusCode = _statusCode, headers = _headers;

- init
{
	self = [super init];

	@try {
		_protocolVersion.major = 1;
		_protocolVersion.minor = 1;
		_headers = [[OFDictionary alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_headers release];

Modified src/OFHTTPServer.h from [6f778fd782] to [e0793a9509].

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*!
 * @class OFHTTPServer OFHTTPServer.h ObjFW/OFHTTPServer.h
 *
 * @brief A class for creating a simple HTTP server inside of applications.
 */
@interface OFHTTPServer: OFObject
{
	OFString *_host;
	uint16_t _port;
	id <OFHTTPServerDelegate> _delegate;
	OFString *_name;
	OFTCPSocket *_listeningSocket;
}

/*!
 * The host on which the HTTP server will listen.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *host;








|

|
|
|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*!
 * @class OFHTTPServer OFHTTPServer.h ObjFW/OFHTTPServer.h
 *
 * @brief A class for creating a simple HTTP server inside of applications.
 */
@interface OFHTTPServer: OFObject
{
	OFString *_Nullable _host;
	uint16_t _port;
	id <OFHTTPServerDelegate> _Nullable _delegate;
	OFString *_Nullable _name;
	OFTCPSocket *_Nullable _listeningSocket;
}

/*!
 * The host on which the HTTP server will listen.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *host;

Modified src/OFINICategory+Private.h from [59ee9ce154] to [5583b4a433].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

@class OFStream;

@interface OFINICategory ()
- (instancetype)of_init OF_METHOD_FAMILY(init);
- (void)of_parseLine: (OFString *)line;
- (bool)of_writeToStream: (OFStream *)stream
		encoding: (of_string_encoding_t)encoding
		   first: (bool)first;
@end

OF_ASSUME_NONNULL_END







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

@class OFStream;

@interface OFINICategory ()
- (instancetype)of_initWithName: (OFString *)name OF_METHOD_FAMILY(init);
- (void)of_parseLine: (OFString *)line;
- (bool)of_writeToStream: (OFStream *)stream
		encoding: (of_string_encoding_t)encoding
		   first: (bool)first;
@end

OF_ASSUME_NONNULL_END

Modified src/OFINICategory.m from [77ec98f4c0] to [95cd2a6086].

117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
	[super dealloc];
}
@end

@implementation OFINICategory
@synthesize name = _name;

- (instancetype)of_init
{
	self = [super init];

	@try {

		_lines = [[OFMutableArray alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;







|




>







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
	[super dealloc];
}
@end

@implementation OFINICategory
@synthesize name = _name;

- (instancetype)of_initWithName: (OFString *)name
{
	self = [super init];

	@try {
		_name = [name copy];
		_lines = [[OFMutableArray alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
		if ([line isKindOfClass: [OFINICategory_Comment class]]) {
			OFINICategory_Comment *comment = line;
			[stream writeFormat: @"%@\r\n", comment->_comment];
		} else if ([line isKindOfClass: [OFINICategory_Pair class]]) {
			OFINICategory_Pair *pair = line;
			OFString *key = escapeString(pair->_key);
			OFString *value = escapeString(pair->_value);
			OFString *line = [OFString
			    stringWithFormat: @"%@=%@\r\n", key, value];

			[stream writeString: line
				   encoding: encoding];
		} else
			@throw [OFInvalidArgumentException exception];
	}

	return true;
}
@end







|


|








506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
		if ([line isKindOfClass: [OFINICategory_Comment class]]) {
			OFINICategory_Comment *comment = line;
			[stream writeFormat: @"%@\r\n", comment->_comment];
		} else if ([line isKindOfClass: [OFINICategory_Pair class]]) {
			OFINICategory_Pair *pair = line;
			OFString *key = escapeString(pair->_key);
			OFString *value = escapeString(pair->_value);
			OFString *tmp = [OFString
			    stringWithFormat: @"%@=%@\r\n", key, value];

			[stream writeString: tmp
				   encoding: encoding];
		} else
			@throw [OFInvalidArgumentException exception];
	}

	return true;
}
@end

Modified src/OFINIFile.m from [5212c0b9d0] to [01663115e7].

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
	void *pool = objc_autoreleasePoolPush();
	OFINICategory *category;

	for (category in _categories)
		if ([[category name] isEqual: name])
			return category;

	category = [[[OFINICategory alloc] of_init] autorelease];
	[category setName: name];
	[_categories addObject: category];

	objc_autoreleasePoolPop(pool);

	return category;
}








|
<







100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
	void *pool = objc_autoreleasePoolPush();
	OFINICategory *category;

	for (category in _categories)
		if ([[category name] isEqual: name])
			return category;

	category = [[[OFINICategory alloc] of_initWithName: name] autorelease];

	[_categories addObject: category];

	objc_autoreleasePoolPop(pool);

	return category;
}

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
			if (![line hasSuffix: @"]"])
				@throw [OFInvalidFormatException exception];

			categoryName = [line substringWithRange:
			    of_range(1, [line length] - 2)];

			category = [[[OFINICategory alloc]
			    of_init] autorelease];
			[category setName: categoryName];
			[_categories addObject: category];
		} else {
			if (category == nil)
				@throw [OFInvalidFormatException exception];

			[category of_parseLine: line];
		}







<
|







141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
			if (![line hasSuffix: @"]"])
				@throw [OFInvalidFormatException exception];

			categoryName = [line substringWithRange:
			    of_range(1, [line length] - 2)];

			category = [[[OFINICategory alloc]

			    of_initWithName: categoryName] autorelease];
			[_categories addObject: category];
		} else {
			if (category == nil)
				@throw [OFInvalidFormatException exception];

			[category of_parseLine: line];
		}

Modified src/OFInflateStream.h from [2b188fa81c] to [d858471aa3].

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52

53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
#endif
	OFStream *_stream;
	uint8_t _buffer[OF_INFLATE_STREAM_BUFFER_SIZE];
	uint16_t _bufferIndex, _bufferLength;
	uint8_t _byte;
	uint8_t _bitIndex, _savedBitsLength;
	uint16_t _savedBits;
	uint8_t *_slidingWindow;
	uint16_t _slidingWindowIndex, _slidingWindowMask;
	int _state;
	union {
		struct {
			uint8_t position;
			uint8_t length[4];
		} uncompressedHeader;
		struct {
			uint16_t position, length;
		} uncompressed;
		struct {

			struct huffman_tree *litLenTree, *distTree;

			struct huffman_tree *codeLenTree, *treeIter;
			uint8_t *lengths;
			uint16_t receivedCount;
			uint8_t value, litLenCodesCount, distCodesCount;
			uint8_t codeLenCodesCount;
		} huffmanTree;
		struct {

			struct huffman_tree *litLenTree, *distTree;
			struct huffman_tree *treeIter;
			int state;
			uint16_t value, length, distance, extraBits;
		} huffman;
	} _context;
	bool _inLastBlock, _atEndOfStream;
}








|











>
|
>
|
|





>
|
|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#endif
	OFStream *_stream;
	uint8_t _buffer[OF_INFLATE_STREAM_BUFFER_SIZE];
	uint16_t _bufferIndex, _bufferLength;
	uint8_t _byte;
	uint8_t _bitIndex, _savedBitsLength;
	uint16_t _savedBits;
	uint8_t *_Nullable _slidingWindow;
	uint16_t _slidingWindowIndex, _slidingWindowMask;
	int _state;
	union {
		struct {
			uint8_t position;
			uint8_t length[4];
		} uncompressedHeader;
		struct {
			uint16_t position, length;
		} uncompressed;
		struct {
			struct huffman_tree *_Nullable litLenTree;
			struct huffman_tree *_Nullable distTree;
			struct huffman_tree *_Nullable codeLenTree;
			struct huffman_tree *_Nullable treeIter;
			uint8_t *_Nullable lengths;
			uint16_t receivedCount;
			uint8_t value, litLenCodesCount, distCodesCount;
			uint8_t codeLenCodesCount;
		} huffmanTree;
		struct {
			struct huffman_tree *_Nullable litLenTree;
			struct huffman_tree *_Nullable distTree;
			struct huffman_tree *_Nullable treeIter;
			int state;
			uint16_t value, length, distance, extraBits;
		} huffman;
	} _context;
	bool _inLastBlock, _atEndOfStream;
}

Modified src/OFIntrospection.h from [be287d0416] to [69d1f3e9bd].

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
 *
 * @brief A class for describing a property.
 */
@interface OFProperty: OFObject
{
	OFString *_name;
	unsigned _attributes;
	OFString *_getter, *_setter;
}

/*!
 * The name of the property.
 */
@property (readonly, nonatomic) OFString *name;








|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
 *
 * @brief A class for describing a property.
 */
@interface OFProperty: OFObject
{
	OFString *_name;
	unsigned _attributes;
	OFString *_Nullable _getter, *_Nullable _setter;
}

/*!
 * The name of the property.
 */
@property (readonly, nonatomic) OFString *name;

Modified src/OFIntrospection.m from [0844281f73] to [b70bed1465].

383
384
385
386
387
388
389



390
391
392
393
394
395
396
397
398
}
#elif defined(OF_APPLE_RUNTIME)
- (instancetype)of_initWithIvar: (Ivar)ivar
{
	self = [super init];

	@try {



		_name = [[OFString alloc]
		    initWithUTF8String: ivar_getName(ivar)];
		_typeEncoding = ivar_getTypeEncoding(ivar);
		_offset = ivar_getOffset(ivar);
	} @catch (id e) {
		[self release];
		@throw e;
	}








>
>
>
|
|







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
}
#elif defined(OF_APPLE_RUNTIME)
- (instancetype)of_initWithIvar: (Ivar)ivar
{
	self = [super init];

	@try {
		const char *name = ivar_getName(ivar);

		if (name != NULL)
			_name = [[OFString alloc] initWithUTF8String: name];

		_typeEncoding = ivar_getTypeEncoding(ivar);
		_offset = ivar_getOffset(ivar);
	} @catch (id e) {
		[self release];
		@throw e;
	}

Modified src/OFKernelEventObserver.h from [46bd90f11e] to [25392c4526].

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 */
@interface OFKernelEventObserver: OFObject
{
	OFMutableArray OF_GENERIC(id <OFReadyForReadingObserving>)
	    *_readObjects;
	OFMutableArray OF_GENERIC(id <OFReadyForWritingObserving>)
	    *_writeObjects;
	id <OFKernelEventObserverDelegate> _delegate;
#ifdef OF_HAVE_PIPE
	int _cancelFD[2];
#else
	of_socket_t _cancelFD[2];
	struct sockaddr_in _cancelAddr;
#endif
#ifdef OF_HAVE_THREADS







|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 */
@interface OFKernelEventObserver: OFObject
{
	OFMutableArray OF_GENERIC(id <OFReadyForReadingObserving>)
	    *_readObjects;
	OFMutableArray OF_GENERIC(id <OFReadyForWritingObserving>)
	    *_writeObjects;
	id <OFKernelEventObserverDelegate> _Nullable _delegate;
#ifdef OF_HAVE_PIPE
	int _cancelFD[2];
#else
	of_socket_t _cancelFD[2];
	struct sockaddr_in _cancelAddr;
#endif
#ifdef OF_HAVE_THREADS

Modified src/OFKeyValueCoding.h from [f12732c01d] to [b40de73f7d].

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

/*!
 * @brief Set the value for the specified key
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString *)key;

/*!
 * @brief This is called by @ref setValue:forKey: if the specified key does not
 *	  exist.
 *
 * By default, this throws an @ref OFUndefinedKeyException.







|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

/*!
 * @brief Set the value for the specified key
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (id)value
	  forKey: (OFString *)key;

/*!
 * @brief This is called by @ref setValue:forKey: if the specified key does not
 *	  exist.
 *
 * By default, this throws an @ref OFUndefinedKeyException.

Modified src/OFList.h from [156b26bb39] to [2bcd2e7a45].

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 *
 * @brief A list object.
 *
 * A struct that contains a pointer to the next list object, the previous list
 * object and the object.
 */
struct of_list_object_t {
	/// A pointer to the next list object in the list
	of_list_object_t *next;
	/// A pointer to the previous list object in the list
	of_list_object_t *previous;
	/// The object for the list object
	id __unsafe_unretained object;
};

/*!
 * @class OFList OFList.h ObjFW/OFList.h
 *
 * @brief A class which provides easy to use double-linked lists.
 */
@interface OFList OF_GENERIC(ObjectType): OFObject <OFCopying, OFCollection,
    OFSerialization>
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# define ObjectType id
#endif
{
	of_list_object_t *_firstListObject;
	of_list_object_t *_lastListObject;
	size_t		 _count;
	unsigned long	 _mutations;
}

/*!
 * The first list object of the list.
 */
@property OF_NULLABLE_PROPERTY (readonly, nonatomic)
    of_list_object_t *firstListObject;







|
|
|
|
|














|
|
|
|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 *
 * @brief A list object.
 *
 * A struct that contains a pointer to the next list object, the previous list
 * object and the object.
 */
struct of_list_object_t {
	/*! A pointer to the next list object in the list */
	of_list_object_t *_Nullable next;
	/*! A pointer to the previous list object in the list */
	of_list_object_t *_Nullable previous;
	/*! The object for the list object */
	id __unsafe_unretained object;
};

/*!
 * @class OFList OFList.h ObjFW/OFList.h
 *
 * @brief A class which provides easy to use double-linked lists.
 */
@interface OFList OF_GENERIC(ObjectType): OFObject <OFCopying, OFCollection,
    OFSerialization>
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# define ObjectType id
#endif
{
	of_list_object_t *_Nullable _firstListObject;
	of_list_object_t *_Nullable _lastListObject;
	size_t _count;
	unsigned long  _mutations;
}

/*!
 * The first list object of the list.
 */
@property OF_NULLABLE_PROPERTY (readonly, nonatomic)
    of_list_object_t *firstListObject;
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*!
 * @brief Checks whether the list contains an object equal to the specified
 *	  object.
 *
 * @param object The object which is checked for being in the list
 * @return A boolean whether the list contains the specified object
 */
- (bool)containsObject: (nullable ObjectType)object;

/*!
 * @brief Checks whether the list contains an object with the specified address.
 *
 * @param object The object which is checked for being in the list
 * @return A boolean whether the list contains an object with the specified
 *	   address
 */
- (bool)containsObjectIdenticalTo: (nullable ObjectType)object;

/*!
 * @brief Returns an OFEnumerator to enumerate through all objects of the list.
 *
 * @returns An OFEnumerator to enumerate through all objects of the list
 */
- (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator;







|








|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*!
 * @brief Checks whether the list contains an object equal to the specified
 *	  object.
 *
 * @param object The object which is checked for being in the list
 * @return A boolean whether the list contains the specified object
 */
- (bool)containsObject: (ObjectType)object;

/*!
 * @brief Checks whether the list contains an object with the specified address.
 *
 * @param object The object which is checked for being in the list
 * @return A boolean whether the list contains an object with the specified
 *	   address
 */
- (bool)containsObjectIdenticalTo: (ObjectType)object;

/*!
 * @brief Returns an OFEnumerator to enumerate through all objects of the list.
 *
 * @returns An OFEnumerator to enumerate through all objects of the list
 */
- (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator;
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# undef ObjectType
#endif
@end

@interface OFListEnumerator: OFEnumerator
{
	OFList		 *_list;
	of_list_object_t *_current;
	unsigned long	 _mutations;
	unsigned long	 *_mutationsPtr;
}

-     initWithList: (OFList *)list
  mutationsPointer: (unsigned long *)mutationsPtr;
@end

OF_ASSUME_NONNULL_END







|
|
|
|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# undef ObjectType
#endif
@end

@interface OFListEnumerator: OFEnumerator
{
	OFList *_list;
	of_list_object_t *_Nullable _current;
	unsigned long _mutations;
	unsigned long *_Nullable _mutationsPtr;
}

-     initWithList: (OFList *)list
  mutationsPointer: (unsigned long *)mutationsPtr;
@end

OF_ASSUME_NONNULL_END

Modified src/OFLocalization.h from [f635a4f99c] to [03b54489d7].

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*!
 * @class OFLocalization OFLocalization.h ObjFW/OFLocalization.h
 *
 * @brief A class for querying the locale and retrieving localized strings.
 */
@interface OFLocalization: OFObject
{
	OFString *_language;
	OFString *_territory;
	of_string_encoding_t _encoding;
	OFString *_decimalPoint;
	OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString *, id) *)
	    *_localizedStrings;
}

/**







|
<







32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
/*!
 * @class OFLocalization OFLocalization.h ObjFW/OFLocalization.h
 *
 * @brief A class for querying the locale and retrieving localized strings.
 */
@interface OFLocalization: OFObject
{
	OFString *_Nullable _language, *_Nullable _territory;

	of_string_encoding_t _encoding;
	OFString *_decimalPoint;
	OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString *, id) *)
	    *_localizedStrings;
}

/**

Modified src/OFMapTable.h from [9ffd8ae151] to [59f43aca32].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44

/*!
 * @struct of_map_table_functions_t OFMapTable.h ObjFW/OFMapTable.h
 *
 * @brief A struct describing the functions to be used by the map table.
 */
typedef struct {
	/// The function to retain keys / objects
	void *_Nonnull (*_Nullable retain)(void *object);
	/// The function to release keys / objects
	void (*_Nullable release)(void *object);
	/// The function to hash keys
	uint32_t (*_Nullable hash)(void *object);
	/// The function to compare keys / objects
	bool (*_Nullable equal)(void *object1, void *object2);

} of_map_table_functions_t;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief A block for enumerating an OFMapTable.
 *
 * @param key The current key







|
|
|
|
|
|
|
|
>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

/*!
 * @struct of_map_table_functions_t OFMapTable.h ObjFW/OFMapTable.h
 *
 * @brief A struct describing the functions to be used by the map table.
 */
typedef struct {
	/*! The function to retain keys / objects */
	void *_Nullable (*_Nullable retain)(void *_Nullable object);
	/*! The function to release keys / objects */
	void (*_Nullable release)(void *_Nullable object);
	/*! The function to hash keys */
	uint32_t (*_Nullable hash)(void *_Nullable object);
	/*! The function to compare keys / objects */
	bool (*_Nullable equal)(void *_Nullable object1,
	    void *_Nullable object2);
} of_map_table_functions_t;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief A block for enumerating an OFMapTable.
 *
 * @param key The current key
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 *
 * @brief A class similar to OFDictionary, but providing more options how keys
 *	  and objects should be retained, released, compared and hashed.
 */
@interface OFMapTable: OFObject <OFCopying, OFFastEnumeration>
{
	of_map_table_functions_t _keyFunctions, _objectFunctions;
	struct of_map_table_bucket **_buckets;
	uint32_t _count, _capacity;
	uint8_t _rotate;
	unsigned long _mutations;
}

/*!
 * The key functions used by the map table.







|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 *
 * @brief A class similar to OFDictionary, but providing more options how keys
 *	  and objects should be retained, released, compared and hashed.
 */
@interface OFMapTable: OFObject <OFCopying, OFFastEnumeration>
{
	of_map_table_functions_t _keyFunctions, _objectFunctions;
	struct of_map_table_bucket *_Nonnull *_Nullable _buckets;
	uint32_t _count, _capacity;
	uint8_t _rotate;
	unsigned long _mutations;
}

/*!
 * The key functions used by the map table.
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
 *
 * @brief A class which provides methods to enumerate through an OFMapTable's
 *	  keys or objects.
 */
@interface OFMapTableEnumerator: OFObject
{
	OFMapTable *_mapTable;
	struct of_map_table_bucket **_buckets;
	uint32_t _capacity;
	unsigned long _mutations;
	unsigned long *_mutationsPtr;
	uint32_t _position;
}

- init OF_UNAVAILABLE;

/*!
 * @brief Returns the next object.
 *
 * @return The next object
 */
- (void *)nextObject;

/*!
 * @brief Resets the enumerator, so the next call to @ref nextKey returns the
 *	  first key again.
 */
- (void)reset;
@end

OF_ASSUME_NONNULL_END







|


|










|









234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
 *
 * @brief A class which provides methods to enumerate through an OFMapTable's
 *	  keys or objects.
 */
@interface OFMapTableEnumerator: OFObject
{
	OFMapTable *_mapTable;
	struct of_map_table_bucket *_Nonnull *_Nullable _buckets;
	uint32_t _capacity;
	unsigned long _mutations;
	unsigned long *_Nullable _mutationsPtr;
	uint32_t _position;
}

- init OF_UNAVAILABLE;

/*!
 * @brief Returns the next object.
 *
 * @return The next object
 */
- (nullable void *)nextObject;

/*!
 * @brief Resets the enumerator, so the next call to @ref nextKey returns the
 *	  first key again.
 */
- (void)reset;
@end

OF_ASSUME_NONNULL_END

Modified src/OFMapTable.m from [9a08c57256] to [1517e60617].

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	if (mapTable->_count != _count ||
	    mapTable->_keyFunctions.equal != _keyFunctions.equal ||
	    mapTable->_objectFunctions.equal != _objectFunctions.equal)
		return false;

	for (uint32_t i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			void *object =
			    [mapTable objectForKey: _buckets[i]->key];

			if (!_objectFunctions.equal(object,
			    _buckets[i]->object))
				return false;
		}
	}

	return true;
}







|


|







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	if (mapTable->_count != _count ||
	    mapTable->_keyFunctions.equal != _keyFunctions.equal ||
	    mapTable->_objectFunctions.equal != _objectFunctions.equal)
		return false;

	for (uint32_t i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			void *objectIter =
			    [mapTable objectForKey: _buckets[i]->key];

			if (!_objectFunctions.equal(objectIter,
			    _buckets[i]->object))
				return false;
		}
	}

	return true;
}

Modified src/OFMutableURL.m from [60a5553f44] to [d83d33a394].

14
15
16
17
18
19
20

21
22
23
24
25
26
27
 * file.
 */

#include "config.h"

#import "OFMutableURL.h"
#import "OFURL+Private.h"


@implementation OFMutableURL
@dynamic scheme, host, port, user, password, path, parameters, query, fragment;

+ (instancetype)URL
{
	return [[[self alloc] init] autorelease];







>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * file.
 */

#include "config.h"

#import "OFMutableURL.h"
#import "OFURL+Private.h"
#import "OFString.h"

@implementation OFMutableURL
@dynamic scheme, host, port, user, password, path, parameters, query, fragment;

+ (instancetype)URL
{
	return [[[self alloc] init] autorelease];

Modified src/OFMutex.h from [60b100f7b5] to [0ee6091df5].

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 *
 * @brief A class for creating mutual exclusions.
 */
@interface OFMutex: OFObject <OFLocking>
{
	of_mutex_t _mutex;
	bool _initialized;
	OFString *_name;
}

/*!
 * @brief Creates a new mutex.
 *
 * @return A new autoreleased mutex.
 */
+ (instancetype)mutex;
@end

OF_ASSUME_NONNULL_END







|











26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 *
 * @brief A class for creating mutual exclusions.
 */
@interface OFMutex: OFObject <OFLocking>
{
	of_mutex_t _mutex;
	bool _initialized;
	OFString *_Nullable _name;
}

/*!
 * @brief Creates a new mutex.
 *
 * @return A new autoreleased mutex.
 */
+ (instancetype)mutex;
@end

OF_ASSUME_NONNULL_END

Modified src/OFObject.h from [9973173cd1] to [7fadabcfb1].

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
- (Class)class;

/*!
 * @brief Returns the superclass of the object.
 *
 * @return The superclass of the object
 */
- (Class)superclass;

/*!
 * @brief Returns a boolean whether the object of the specified kind.
 *
 * @param class_ The class whose kind is checked
 * @return A boolean whether the object is of the specified kind
 */







|







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
- (Class)class;

/*!
 * @brief Returns the superclass of the object.
 *
 * @return The superclass of the object
 */
- (nullable Class)superclass;

/*!
 * @brief Returns a boolean whether the object of the specified kind.
 *
 * @param class_ The class whose kind is checked
 * @return A boolean whether the object is of the specified kind
 */
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
+ (bool)isSubclassOfClass: (Class)class_;

/*!
 * @brief Returns the superclass of the class.
 *
 * @return The superclass of the class
 */
+ (Class)superclass;

/*!
 * @brief Checks whether instances of the class respond to a given selector.
 *
 * @param selector The selector which should be checked for respondence
 * @return A boolean whether instances of the class respond to the specified
 *	   selector







|







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
+ (bool)isSubclassOfClass: (Class)class_;

/*!
 * @brief Returns the superclass of the class.
 *
 * @return The superclass of the class
 */
+ (nullable Class)superclass;

/*!
 * @brief Checks whether instances of the class respond to a given selector.
 *
 * @param selector The selector which should be checked for respondence
 * @return A boolean whether instances of the class respond to the specified
 *	   selector
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659
660
661
662
663

664
665
666
667
668
669
670
671
672
673

/*!
 * @brief Allocates memory and stores it in the object's memory pool.
 *
 * It will be freed automatically when the object is deallocated.
 *
 * @param size The size of the memory to allocate
 * @return A pointer to the allocated memory

 */
- (void *)allocMemoryWithSize: (size_t)size;

/*!
 * @brief Allocates memory for the specified number of items and stores it in
 *	  the object's memory pool.
 *
 * It will be freed automatically when the object is deallocated.
 *
 * @param size The size of each item to allocate
 * @param count The number of items to allocate
 * @return A pointer to the allocated memory

 */
- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count;

/*!
 * @brief Resizes memory in the object's memory pool to the specified size.
 *
 * If the pointer is NULL, this is equivalent to allocating memory.
 * If the size is 0, this is equivalent to freeing memory.
 *







|
>

|









|
>

|
|







644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675

/*!
 * @brief Allocates memory and stores it in the object's memory pool.
 *
 * It will be freed automatically when the object is deallocated.
 *
 * @param size The size of the memory to allocate
 * @return A pointer to the allocated memory. May return NULL if the specified
 *	   size is 0.
 */
- (nullable void *)allocMemoryWithSize: (size_t)size;

/*!
 * @brief Allocates memory for the specified number of items and stores it in
 *	  the object's memory pool.
 *
 * It will be freed automatically when the object is deallocated.
 *
 * @param size The size of each item to allocate
 * @param count The number of items to allocate
 * @return A pointer to the allocated memory. May return NULL if the specified
 *	   size or count is 0.
 */
- (nullable void *)allocMemoryWithSize: (size_t)size
				 count: (size_t)count;

/*!
 * @brief Resizes memory in the object's memory pool to the specified size.
 *
 * If the pointer is NULL, this is equivalent to allocating memory.
 * If the size is 0, this is equivalent to freeing memory.
 *

Modified src/OFObject.m from [c072b00a16] to [4d9911935a].

468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
				withMethodFromClass: class];
		}
	} @finally {
		free(methodList);
	}
#endif

	[self inheritMethodsFromClass: [class superclass]];
}

+ (BOOL)resolveClassMethod: (SEL)selector
{
	return NO;
}








|







468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
				withMethodFromClass: class];
		}
	} @finally {
		free(methodList);
	}
#endif

	[self inheritMethodsFromClass: superclass];
}

+ (BOOL)resolveClassMethod: (SEL)selector
{
	return NO;
}

Modified src/OFOptionsParser.h from [b82c75fff0] to [b57dc17fb3].

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
@interface OFOptionsParser: OFObject
{
	of_options_parser_option_t *_options;
	OFMapTable *_longOptions;
	OFArray OF_GENERIC(OFString *) *_arguments;
	size_t _index, _subIndex;
	of_unichar_t _lastOption;
	OFString *_lastLongOption, *_argument;
	bool _done;
}

/*!
 * The last parsed option.
 *
 * If @ref nextOption returned `?` or `:`, this returns the option which was







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
@interface OFOptionsParser: OFObject
{
	of_options_parser_option_t *_options;
	OFMapTable *_longOptions;
	OFArray OF_GENERIC(OFString *) *_arguments;
	size_t _index, _subIndex;
	of_unichar_t _lastOption;
	OFString *_Nullable _lastLongOption, *_Nullable _argument;
	bool _done;
}

/*!
 * The last parsed option.
 *
 * If @ref nextOption returned `?` or `:`, this returns the option which was

Modified src/OFRecursiveMutex.h from [8408c300d0] to [6ef5e2c06f].

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 * @brief A class for creating mutual exclusions which can be entered
 *	  recursively.
 */
@interface OFRecursiveMutex: OFObject <OFLocking>
{
	of_rmutex_t _rmutex;
	bool _initialized;
	OFString *_name;
}

/*!
 * @brief Creates a new recursive mutex.
 *
 * @return A new autoreleased recursive mutex.
 */
+ (instancetype)mutex;
@end

OF_ASSUME_NONNULL_END







|











27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 * @brief A class for creating mutual exclusions which can be entered
 *	  recursively.
 */
@interface OFRecursiveMutex: OFObject <OFLocking>
{
	of_rmutex_t _rmutex;
	bool _initialized;
	OFString *_Nullable _name;
}

/*!
 * @brief Creates a new recursive mutex.
 *
 * @return A new autoreleased recursive mutex.
 */
+ (instancetype)mutex;
@end

OF_ASSUME_NONNULL_END

Modified src/OFRunLoop.m from [50df1150e8] to [2bcc651795].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35


36
37
38
39
40
41
42
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <assert.h>


#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"
#import "OFDictionary.h"
#ifdef OF_HAVE_SOCKETS
# import "OFKernelEventObserver.h"
#endif
#import "OFThread.h"
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
# import "OFCondition.h"
#endif
#import "OFSortedList.h"
#import "OFTimer.h"
#import "OFTimer+Private.h"
#import "OFDate.h"



static OFRunLoop *mainRunLoop = nil;

#ifdef OF_HAVE_SOCKETS
@interface OFRunLoop_QueueItem: OFObject
{
@public







>
















>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <assert.h>
#include <errno.h>

#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"
#import "OFDictionary.h"
#ifdef OF_HAVE_SOCKETS
# import "OFKernelEventObserver.h"
#endif
#import "OFThread.h"
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
# import "OFCondition.h"
#endif
#import "OFSortedList.h"
#import "OFTimer.h"
#import "OFTimer+Private.h"
#import "OFDate.h"

#import "OFObserveFailedException.h"

static OFRunLoop *mainRunLoop = nil;

#ifdef OF_HAVE_SOCKETS
@interface OFRunLoop_QueueItem: OFObject
{
@public
715
716
717
718
719
720
721

722
723




724
725
726
727
728
729
730
731
732
733
734
735
736
737

738




739
740
741
742
743
744
745
				timeout = [[nextTimer earlierDate: deadline]
				    timeIntervalSinceNow];

			if (timeout < 0)
				timeout = 0;

#if defined(OF_HAVE_SOCKETS)

			[_kernelEventObserver
			    observeForTimeInterval: timeout];




#elif defined(OF_HAVE_THREADS)
			[_condition lock];
			[_condition waitForTimeInterval: timeout];
			[_condition unlock];
#else
			[OFThread sleepForTimeInterval: timeout];
#endif
		} else {
			/*
			 * No more timers and no deadline: Just watch for I/O
			 * until we get an event. If a timer is added by
			 * another thread, it cancels the observe.
			 */
#if defined(OF_HAVE_SOCKETS)

			[_kernelEventObserver observe];




#elif defined(OF_HAVE_THREADS)
			[_condition lock];
			[_condition wait];
			[_condition unlock];
#else
			[OFThread sleepForTimeInterval: 86400];
#endif







>
|
|
>
>
>
>














>
|
>
>
>
>







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
				timeout = [[nextTimer earlierDate: deadline]
				    timeIntervalSinceNow];

			if (timeout < 0)
				timeout = 0;

#if defined(OF_HAVE_SOCKETS)
			@try {
				[_kernelEventObserver
				    observeForTimeInterval: timeout];
			} @catch (OFObserveFailedException *e) {
				if ([e errNo] != EINTR)
					@throw e;
			}
#elif defined(OF_HAVE_THREADS)
			[_condition lock];
			[_condition waitForTimeInterval: timeout];
			[_condition unlock];
#else
			[OFThread sleepForTimeInterval: timeout];
#endif
		} else {
			/*
			 * No more timers and no deadline: Just watch for I/O
			 * until we get an event. If a timer is added by
			 * another thread, it cancels the observe.
			 */
#if defined(OF_HAVE_SOCKETS)
			@try {
				[_kernelEventObserver observe];
			} @catch (OFObserveFailedException *e) {
				if ([e errNo] != EINTR)
					@throw e;
			}
#elif defined(OF_HAVE_THREADS)
			[_condition lock];
			[_condition wait];
			[_condition unlock];
#else
			[OFThread sleepForTimeInterval: 86400];
#endif

Modified src/OFSet.h from [b570ea6601] to [28701b2ea5].

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
- (OFArray OF_GENERIC(ObjectType) *)allObjects;

/*!
 * @brief Returns an arbitrary object in the set.
 *
 * @return An arbitrary object in the set
 */
- (ObjectType)anyObject;

/*!
 * @brief Checks whether the set contains an object equal to the specified
 *	  object.
 *
 * @param object The object which is checked for being in the set
 * @return A boolean whether the set contains the specified object
 */
- (bool)containsObject: (nullable ObjectType)object;

/*!
 * @brief Returns the value for the specified key
 *
 * If the key starts with an `@`, the `@` is stripped and
 * `[super valueForKey:]` is called.
 * If the key does not start with an `@`, a new set with the value for the







|








|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
- (OFArray OF_GENERIC(ObjectType) *)allObjects;

/*!
 * @brief Returns an arbitrary object in the set.
 *
 * @return An arbitrary object in the set
 */
- (nullable ObjectType)anyObject;

/*!
 * @brief Checks whether the set contains an object equal to the specified
 *	  object.
 *
 * @param object The object which is checked for being in the set
 * @return A boolean whether the set contains the specified object
 */
- (bool)containsObject: (ObjectType)object;

/*!
 * @brief Returns the value for the specified key
 *
 * If the key starts with an `@`, the `@` is stripped and
 * `[super valueForKey:]` is called.
 * If the key does not start with an `@`, a new set with the value for the
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
 * each object.
 *
 * @note A @ref OFNull value is translated to nil!
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString *)key;

/*!
 * @brief Returns an OFEnumerator to enumerate through all objects of the set.
 *
 * @returns An OFEnumerator to enumerate through all objects of the set
 */







|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
 * each object.
 *
 * @note A @ref OFNull value is translated to nil!
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (id)value
	  forKey: (OFString *)key;

/*!
 * @brief Returns an OFEnumerator to enumerate through all objects of the set.
 *
 * @returns An OFEnumerator to enumerate through all objects of the set
 */

Modified src/OFSet.m from [62db370766] to [9a3d14535d].

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
- (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (id)valueForKey: (OFString *)key
{
	OFMutableSet *ret;

	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();
		id ret;

		key = [key substringWithRange: of_range(1, [key length] - 1)];
		ret = [[super valueForKey: key] retain];

		objc_autoreleasePoolPop(pool);

		return [ret autorelease];







|



<







209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
- (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (id)valueForKey: (OFString *)key
{
	id ret;

	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();


		key = [key substringWithRange: of_range(1, [key length] - 1)];
		ret = [[super valueForKey: key] retain];

		objc_autoreleasePoolPop(pool);

		return [ret autorelease];
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
		[super setValue: value
			 forKey: key];

		objc_autoreleasePoolPop(pool);
		return;
	}

	if (value == [OFNull null])
		value = nil;

	for (id object in self)
		[object setValue: value
			  forKey: key];
}

- (bool)containsObject: (id)object
{







<
<
<







250
251
252
253
254
255
256



257
258
259
260
261
262
263
		[super setValue: value
			 forKey: key];

		objc_autoreleasePoolPop(pool);
		return;
	}




	for (id object in self)
		[object setValue: value
			  forKey: key];
}

- (bool)containsObject: (id)object
{

Modified src/OFStream.h from [fc84511d6f] to [1cb5dc2e2d].

90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
    OFReadyForReadingObserving, OFReadyForWritingObserving,
#endif
    OFCopying>
{
#if !defined(OF_SEEKABLE_STREAM_M) && !defined(OF_TCP_SOCKET_M)
@private
#endif

	char *_readBuffer, *_readBufferMemory, *_writeBuffer;
	size_t _readBufferLength, _writeBufferLength;
	bool _writeBuffered, _waitingForDelimiter;
@protected
	bool _blocking;
}

/*!







>
|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    OFReadyForReadingObserving, OFReadyForWritingObserving,
#endif
    OFCopying>
{
#if !defined(OF_SEEKABLE_STREAM_M) && !defined(OF_TCP_SOCKET_M)
@private
#endif
	char *_Nullable _readBuffer, *_Nullable _readBufferMemory;
	char *_Nullable _writeBuffer;
	size_t _readBufferLength, _writeBufferLength;
	bool _writeBuffered, _waitingForDelimiter;
@protected
	bool _blocking;
}

/*!

Modified src/OFStream.m from [d30563e398] to [e48fbb2fa9].

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#import "of_asprintf.h"

#define MIN_READ_SIZE 512

@implementation OFStream
@synthesize of_waitingForDelimiter = _waitingForDelimiter;

#if !defined(OF_WINDOWS) && !defined(OF_MORPHOS)
+ (void)initialize
{
	if (self == [OFStream class])
		signal(SIGPIPE, SIG_IGN);
}
#endif








|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#import "of_asprintf.h"

#define MIN_READ_SIZE 512

@implementation OFStream
@synthesize of_waitingForDelimiter = _waitingForDelimiter;

#if defined(SIGPIPE) && defined(SIG_IGN)
+ (void)initialize
{
	if (self == [OFStream class])
		signal(SIGPIPE, SIG_IGN);
}
#endif

Modified src/OFString+XMLUnescaping.h from [0f77351c40] to [48a186039b].

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 * it is unknown to the callback as well, in which case an exception will be
 * thrown.
 *
 * @param string The string which contains the unknown entity
 * @param entity The name of the entity that is unknown
 * @return A substitution for the entity or `nil`
 */
-	  (OFString *)string: (OFString *)string
  containsUnknownEntityNamed: (OFString *)entity;
@end

@interface OFString (XMLUnescaping)
/*!
 * @brief Unescapes XML in the string.
 */
- (OFString *)stringByXMLUnescaping;







|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 * it is unknown to the callback as well, in which case an exception will be
 * thrown.
 *
 * @param string The string which contains the unknown entity
 * @param entity The name of the entity that is unknown
 * @return A substitution for the entity or `nil`
 */
- (nullable OFString *)string: (OFString *)string
   containsUnknownEntityNamed: (OFString *)entity;
@end

@interface OFString (XMLUnescaping)
/*!
 * @brief Unescapes XML in the string.
 */
- (OFString *)stringByXMLUnescaping;

Modified src/OFString+XMLUnescaping.m from [d6e6b667b8] to [9667538219].

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
					    length: 1];
			else if (entityLength == 3 &&
			    memcmp(entity, "amp", 3) == 0)
				[ret appendCString: "&"
					  encoding: OF_STRING_ENCODING_ASCII
					    length: 1];
			else if (entity[0] == '#') {
				void *pool;
				OFString *tmp;

				pool = objc_autoreleasePoolPush();
				tmp = parseNumericEntity(entity,
				    entityLength);

				if (tmp == nil)
					@throw [OFInvalidFormatException
					    exception];

				[ret appendString: tmp];

				objc_autoreleasePoolPop(pool);
			} else {
				void *pool;
				OFString *name, *tmp;

				pool = objc_autoreleasePoolPush();

				name = [OFString
				    stringWithUTF8String: entity
						  length: entityLength];
				tmp = lookup(context, self, name);

				if (tmp == nil)
					@throw [OFUnknownXMLEntityException
					    exceptionWithEntityName: name];

				[ret appendString: tmp];

				objc_autoreleasePoolPop(pool);
			}

			last = i + 1;
			inEntity = false;
		}
	}








|


|








>
|

|


|











>
|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
					    length: 1];
			else if (entityLength == 3 &&
			    memcmp(entity, "amp", 3) == 0)
				[ret appendCString: "&"
					  encoding: OF_STRING_ENCODING_ASCII
					    length: 1];
			else if (entity[0] == '#') {
				void *pool2;
				OFString *tmp;

				pool2 = objc_autoreleasePoolPush();
				tmp = parseNumericEntity(entity,
				    entityLength);

				if (tmp == nil)
					@throw [OFInvalidFormatException
					    exception];

				[ret appendString: tmp];

				objc_autoreleasePoolPop(pool2);
			} else {
				void *pool2;
				OFString *name, *tmp;

				pool2 = objc_autoreleasePoolPush();

				name = [OFString
				    stringWithUTF8String: entity
						  length: entityLength];
				tmp = lookup(context, self, name);

				if (tmp == nil)
					@throw [OFUnknownXMLEntityException
					    exceptionWithEntityName: name];

				[ret appendString: tmp];

				objc_autoreleasePoolPop(pool2);
			}

			last = i + 1;
			inEntity = false;
		}
	}

Modified src/OFString.h from [f5efa5d129] to [bb11f44cdb].

16
17
18
19
20
21
22






23
24
25
26
27
28
29

#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS
#endif







#include <stdarg.h>
#include <stdint.h>

#import "OFObject.h"
#import "OFSerialization.h"
#import "OFJSONRepresentation.h"







>
>
>
>
>
>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS
#endif

#import "objfw-defs.h"

#ifdef OF_HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#include <stdarg.h>
#include <stdint.h>

#import "OFObject.h"
#import "OFSerialization.h"
#import "OFJSONRepresentation.h"

Modified src/OFString_UTF8.h from [27665fb3c4] to [b15a7ec396].

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
	struct of_string_utf8_ivars {
		char	 *cString;
		size_t	 cStringLength;
		bool	 isUTF8;
		size_t	 length;
		bool	 hashed;
		uint32_t hash;
		char	 *freeWhenDone;
	} *restrict _s;
	struct of_string_utf8_ivars _storage;
}
@end

#ifdef __cplusplus
extern "C" {







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
	struct of_string_utf8_ivars {
		char	 *cString;
		size_t	 cStringLength;
		bool	 isUTF8;
		size_t	 length;
		bool	 hashed;
		uint32_t hash;
		char	 *_Nullable freeWhenDone;
	} *restrict _s;
	struct of_string_utf8_ivars _storage;
}
@end

#ifdef __cplusplus
extern "C" {

Modified src/OFTCPSocket.h from [0d4361b9a8] to [91bb6c7528].

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 *
 * To connect to a server, create a socket and connect it.
 * To create a server, create a socket, bind it and listen on it.
 */
@interface OFTCPSocket: OFStreamSocket
{
	bool _listening;
	struct sockaddr *_address;
	socklen_t _addressLength;
	OFString *_SOCKS5Host;
	uint16_t _SOCKS5Port;
#ifdef OF_WII
	uint16_t _port;
#endif
}

/*!







|

|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 *
 * To connect to a server, create a socket and connect it.
 * To create a server, create a socket, bind it and listen on it.
 */
@interface OFTCPSocket: OFStreamSocket
{
	bool _listening;
	struct sockaddr *_Nullable _address;
	socklen_t _addressLength;
	OFString *_Nullable _SOCKS5Host;
	uint16_t _SOCKS5Port;
#ifdef OF_WII
	uint16_t _port;
#endif
}

/*!

Modified src/OFTCPSocket.m from [56b097e84a] to [9870a76e72].

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
{
	void *pool = objc_autoreleasePoolPush();

	@try {
		[_socket connectToHost: _host
				  port: _port];
	} @catch (OFException *e) {
		_exception = e;
	}

	[self performSelector: @selector(didConnect)
		     onThread: _sourceThread
		waitUntilDone: false];

	objc_autoreleasePoolPop(pool);







|







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
{
	void *pool = objc_autoreleasePoolPush();

	@try {
		[_socket connectToHost: _host
				  port: _port];
	} @catch (OFException *e) {
		_exception = [e retain];
	}

	[self performSelector: @selector(didConnect)
		     onThread: _sourceThread
		waitUntilDone: false];

	objc_autoreleasePoolPop(pool);

Modified src/OFTarArchive.h from [90a272ca60] to [9c5a85aa2e].

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@interface OFTarArchive: OFObject
{
#ifdef OF_TAR_ARCHIVE_ENTRY_M
@public
#endif
	OFStream *_stream;
@protected
	OFTarArchiveEntry *_lastReturnedEntry;
}

/*!
 * @brief Creates a new OFTarArchive object with the specified stream.
 *
 * @param stream A stream from which the tar archive will be read
 * @return A new, autoreleased OFTarArchive







|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@interface OFTarArchive: OFObject
{
#ifdef OF_TAR_ARCHIVE_ENTRY_M
@public
#endif
	OFStream *_stream;
@protected
	OFTarArchiveEntry *_Nullable _lastReturnedEntry;
}

/*!
 * @brief Creates a new OFTarArchive object with the specified stream.
 *
 * @param stream A stream from which the tar archive will be read
 * @return A new, autoreleased OFTarArchive
82
83
84
85
86
87
88
89
90
91
92
 * @warning Calling @ref nextEntry will invalidate all streams returned by the
 *	    previous entry! Reading from an invalidated stream will throw an
 *	    @ref OFReadFailedException!
 *
 * @return The next entry from the tar archive or `nil` if all entries have
 *	   been read
 */
- (OFTarArchiveEntry *)nextEntry;
@end

OF_ASSUME_NONNULL_END







|



82
83
84
85
86
87
88
89
90
91
92
 * @warning Calling @ref nextEntry will invalidate all streams returned by the
 *	    previous entry! Reading from an invalidated stream will throw an
 *	    @ref OFReadFailedException!
 *
 * @return The next entry from the tar archive or `nil` if all entries have
 *	   been read
 */
- (nullable OFTarArchiveEntry *)nextEntry;
@end

OF_ASSUME_NONNULL_END

Modified src/OFTarArchiveEntry.h from [37e5a4326d] to [c755caa995].

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	OFStream *_stream;
	bool _atEndOfStream;
	OFString *_fileName;
	uint32_t _mode;
	uint64_t _size, _toRead;
	OFDate *_modificationDate;
	of_tar_archive_entry_type_t _type;
	OFString *_targetFileName;
	OFString *_owner, *_group;
	uint32_t _deviceMajor, _deviceMinor;
}

/*!
 * The file name of the entry.
 */
@property (readonly, nonatomic) OFString *fileName;







|
|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	OFStream *_stream;
	bool _atEndOfStream;
	OFString *_fileName;
	uint32_t _mode;
	uint64_t _size, _toRead;
	OFDate *_modificationDate;
	of_tar_archive_entry_type_t _type;
	OFString *_Nullable _targetFileName;
	OFString *_Nullable _owner, *_Nullable _group;
	uint32_t _deviceMajor, _deviceMinor;
}

/*!
 * The file name of the entry.
 */
@property (readonly, nonatomic) OFString *fileName;

Modified src/OFTarArchiveEntry.m from [e3da7730a5] to [1b943dcfae].

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100



101
102
103
104

105
106
107
108
109
110
111
		_type = header[156];
		_targetFileName = [stringFromBuffer(header + 157, 100) copy];

		if (_type == '\0')
			_type = OF_TAR_ARCHIVE_ENTRY_TYPE_FILE;

		if (memcmp(header + 257, "ustar\0" "00", 8) == 0) {
			OFString *fileName;

			_owner = [stringFromBuffer(header + 265, 32) copy];
			_group = [stringFromBuffer(header + 297, 32) copy];

			_deviceMajor = (uint32_t)octalValueFromBuffer(
			    header + 329, 8, UINT32_MAX);
			_deviceMinor = (uint32_t)octalValueFromBuffer(
			    header + 337, 8, UINT32_MAX);




			fileName = [OFString stringWithFormat: @"%@/%@",
			    stringFromBuffer(header + 345, 155), _fileName];
			[_fileName release];
			_fileName = [fileName copy];

		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}







|









>
>
>
|
|
|
|
>







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
		_type = header[156];
		_targetFileName = [stringFromBuffer(header + 157, 100) copy];

		if (_type == '\0')
			_type = OF_TAR_ARCHIVE_ENTRY_TYPE_FILE;

		if (memcmp(header + 257, "ustar\0" "00", 8) == 0) {
			OFString *prefix;

			_owner = [stringFromBuffer(header + 265, 32) copy];
			_group = [stringFromBuffer(header + 297, 32) copy];

			_deviceMajor = (uint32_t)octalValueFromBuffer(
			    header + 329, 8, UINT32_MAX);
			_deviceMinor = (uint32_t)octalValueFromBuffer(
			    header + 337, 8, UINT32_MAX);

			prefix = stringFromBuffer(header + 345, 155);
			if ([prefix length] > 0) {
				OFString *fileName = [OFString
				    stringWithFormat: @"%@/%@",
						      prefix, _fileName];
				[_fileName release];
				_fileName = [fileName copy];
			}
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

Modified src/OFThread.h from [f3aa3dc787] to [f66e3d5e03].

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79





80
81
82
83

84
85
86
87
88
89
90
91
92
	enum of_thread_running {
		OF_THREAD_NOT_RUNNING,
		OF_THREAD_RUNNING,
		OF_THREAD_WAITING_FOR_JOIN
	} _running;
	void *_pool;
# ifdef OF_HAVE_BLOCKS
	of_thread_block_t _threadBlock;
# endif
	id _returnValue;
	OFRunLoop *_runLoop;
	OFMutableDictionary *_threadDictionary;
@private
	OFString *_name;
}






#ifdef OF_HAVE_BLOCKS
/*!
 * The block to execute in the thread.
 */

@property (readonly, nonatomic) of_thread_block_t threadBlock;
#endif

/*!
 * @brief Creates a new thread.
 *
 * @return A new, autoreleased thread
 */
+ (instancetype)thread;







|


|


|


>
>
>
>
>
|



>
|
|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
	enum of_thread_running {
		OF_THREAD_NOT_RUNNING,
		OF_THREAD_RUNNING,
		OF_THREAD_WAITING_FOR_JOIN
	} _running;
	void *_pool;
# ifdef OF_HAVE_BLOCKS
	of_thread_block_t _Nullable _threadBlock;
# endif
	id _returnValue;
	OFRunLoop *_Nullable _runLoop;
	OFMutableDictionary *_threadDictionary;
@private
	OFString *_Nullable _name;
}

/*!
 * The name for the thread to use when starting it.
 */
@property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *name;

# ifdef OF_HAVE_BLOCKS
/*!
 * The block to execute in the thread.
 */
@property OF_NULLABLE_PROPERTY (readonly, nonatomic)
    of_thread_block_t threadBlock;
# endif

/*!
 * @brief Creates a new thread.
 *
 * @return A new, autoreleased thread
 */
+ (instancetype)thread;
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*!
 * @brief Returns the run loop for the thread.
 *
 * @return The run loop for the thread
 */
- (OFRunLoop *)runLoop;

/*!
 * @brief Returns the name of the thread or `nil` if none has been set.
 *
 * @return The name of the thread or nil if none has been set
 */
- (nullable OFString *)name;

/*!
 * @brief Sets the name for the thread.
 *
 * @param name The name for the thread
 */
- (void)setName: (nullable OFString *)name;

/*!
 * @brief Returns the priority of the thread.
 *
 * This is a value between -1.0 (meaning lowest priority that still schedules)
 * and +1.0 (meaning highest priority that still allows getting preempted)
 * with normal priority being 0.0 (meaning being the same as the main thread).
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<







204
205
206
207
208
209
210














211
212
213
214
215
216
217
/*!
 * @brief Returns the run loop for the thread.
 *
 * @return The run loop for the thread
 */
- (OFRunLoop *)runLoop;















/*!
 * @brief Returns the priority of the thread.
 *
 * This is a value between -1.0 (meaning lowest priority that still schedules)
 * and +1.0 (meaning highest priority that still allows getting preempted)
 * with normal priority being 0.0 (meaning being the same as the main thread).
 *

Modified src/OFThread.m from [3ff1e2b592] to [3fc1c7c412].

93
94
95
96
97
98
99

100
101
102
103
104
105
106






107
108
109
110
111
112
113
static of_tlskey_t threadSelfKey;
static OFThread *mainThread;

static void
callMain(id object)
{
	OFThread *thread = (OFThread *)object;


	if (!of_tlskey_set(threadSelfKey, thread))
		@throw [OFInitializationFailedException
		    exceptionWithClass: [thread class]];

	thread->_pool = objc_autoreleasePoolPush();







	/*
	 * Nasty workaround for thread implementations which can't return a
	 * pointer on join.
	 */
# ifdef OF_HAVE_BLOCKS
	if (thread->_threadBlock != NULL)
		thread->_returnValue = [thread->_threadBlock() retain];







>







>
>
>
>
>
>







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
static of_tlskey_t threadSelfKey;
static OFThread *mainThread;

static void
callMain(id object)
{
	OFThread *thread = (OFThread *)object;
	OFString *name;

	if (!of_tlskey_set(threadSelfKey, thread))
		@throw [OFInitializationFailedException
		    exceptionWithClass: [thread class]];

	thread->_pool = objc_autoreleasePoolPush();

	name = [thread name];
	if (name != nil)
		of_thread_set_name([name UTF8String]);
	else
		of_thread_set_name(object_getClassName(thread));

	/*
	 * Nasty workaround for thread implementations which can't return a
	 * pointer on join.
	 */
# ifdef OF_HAVE_BLOCKS
	if (thread->_threadBlock != NULL)
		thread->_returnValue = [thread->_threadBlock() retain];
124
125
126
127
128
129
130

131
132
133
134
135
136
137

	[thread release];
}
#endif

@implementation OFThread
#ifdef OF_HAVE_THREADS

# ifdef OF_HAVE_BLOCKS
@synthesize threadBlock = _threadBlock;
# endif

+ (void)initialize
{
	if (self != [OFThread class])







>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

	[thread release];
}
#endif

@implementation OFThread
#ifdef OF_HAVE_THREADS
@synthesize name = _name;
# ifdef OF_HAVE_BLOCKS
@synthesize threadBlock = _threadBlock;
# endif

+ (void)initialize
{
	if (self != [OFThread class])
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

	_running = OF_THREAD_RUNNING;

	if (!of_thread_new(&_thread, callMain, self, &_attr)) {
		[self release];
		@throw [OFThreadStartFailedException exceptionWithThread: self];
	}

	if (_name != nil)
		of_thread_set_name(_thread, [_name UTF8String]);
	else
		of_thread_set_name(_thread, class_getName([self class]));
}

- (id)join
{
	if (_running == OF_THREAD_NOT_RUNNING || !of_thread_join(_thread))
		@throw [OFThreadJoinFailedException exceptionWithThread: self];








<
<
<
<
<







353
354
355
356
357
358
359





360
361
362
363
364
365
366

	_running = OF_THREAD_RUNNING;

	if (!of_thread_new(&_thread, callMain, self, &_attr)) {
		[self release];
		@throw [OFThreadStartFailedException exceptionWithThread: self];
	}





}

- (id)join
{
	if (_running == OF_THREAD_NOT_RUNNING || !of_thread_join(_thread))
		@throw [OFThreadJoinFailedException exceptionWithThread: self];

386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
			_runLoop = [[OFRunLoop alloc] init];
	}
# endif

	return _runLoop;
}

- (OFString *)name
{
	return [[_name copy] autorelease];
}

- (void)setName: (OFString *)name
{
	OFString *old = name;
	_name = [name copy];
	[old release];

	if (_running == OF_THREAD_RUNNING)
		of_thread_set_name(_thread, (_name != nil
		    ? [_name UTF8String] : class_getName([self class])));
}

- (float)priority
{
	return _attr.priority;
}

- (void)setPriority: (float)priority
{







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







389
390
391
392
393
394
395
















396
397
398
399
400
401
402
			_runLoop = [[OFRunLoop alloc] init];
	}
# endif

	return _runLoop;
}

















- (float)priority
{
	return _attr.priority;
}

- (void)setPriority: (float)priority
{

Modified src/OFTimer.h from [a9d9f7dbbd] to [71d9d15e16].

41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
 *
 * @brief A class for creating and firing timers.
 */
@interface OFTimer: OFObject <OFComparing>
{
	OFDate *_fireDate;
	of_time_interval_t _interval;
	id _target, _object1, _object2;

	SEL _selector;
	uint8_t _arguments;
	bool _repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t _block;
#endif
	bool _valid;
#ifdef OF_HAVE_THREADS
	OFCondition *_condition;
	bool _done;
#endif
	OFRunLoop *_inRunLoop;
}

/*!
 * The time interval in which the timer will repeat, if it is a repeating
 * timer.
 */
@property (readonly, nonatomic) of_time_interval_t timeInterval;







|
>











|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
 *
 * @brief A class for creating and firing timers.
 */
@interface OFTimer: OFObject <OFComparing>
{
	OFDate *_fireDate;
	of_time_interval_t _interval;
	id _target;
	id _Nullable _object1, _object2;
	SEL _selector;
	uint8_t _arguments;
	bool _repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t _block;
#endif
	bool _valid;
#ifdef OF_HAVE_THREADS
	OFCondition *_condition;
	bool _done;
#endif
	OFRunLoop *_Nullable _inRunLoop;
}

/*!
 * The time interval in which the timer will repeat, if it is a repeating
 * timer.
 */
@property (readonly, nonatomic) of_time_interval_t timeInterval;

Modified src/OFUDPSocket.h from [05fb60ba2c] to [03e3db3557].

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
 * @param host A pointer to an @ref OFString *. If it is not NULL, it will be
 *	       set to the host of the host / port pair.
 * @param port A pointer to an uint16_t. If it is not NULL, the port of the
 *	       host / port pair will be written to it.
 * @param address The address for which the host and port should be retrieved
 */
+ (void)getHost: (OFString *__autoreleasing _Nonnull *_Nullable)host
	andPort: (uint16_t *_Nullable)port
     forAddress: (of_udp_socket_address_t *)address;

/*!
 * @brief Binds the socket to the specified host and port.
 *
 * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for
 *	       IPv6 to bind to all.







|







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
 * @param host A pointer to an @ref OFString *. If it is not NULL, it will be
 *	       set to the host of the host / port pair.
 * @param port A pointer to an uint16_t. If it is not NULL, the port of the
 *	       host / port pair will be written to it.
 * @param address The address for which the host and port should be retrieved
 */
+ (void)getHost: (OFString *__autoreleasing _Nonnull *_Nullable)host
	andPort: (nullable uint16_t *)port
     forAddress: (of_udp_socket_address_t *)address;

/*!
 * @brief Binds the socket to the specified host and port.
 *
 * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for
 *	       IPv6 to bind to all.

Modified src/OFURL.h from [94ac818021] to [d9d859f93e].

26
27
28
29
30
31
32
33


34
35
36
37
38
39
40
 *
 * @brief A class for parsing URLs and accessing parts of it.
 */
@interface OFURL: OFObject <OFCopying, OFMutableCopying, OFSerialization>
{
	OFString *_scheme, *_host;
	uint16_t _port;
	OFString *_user, *_password, *_path, *_parameters, *_query, *_fragment;


}

/*!
 * The scheme part of the URL.
 */
@property (readonly, nonatomic, copy) OFString *scheme;








|
>
>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 *
 * @brief A class for parsing URLs and accessing parts of it.
 */
@interface OFURL: OFObject <OFCopying, OFMutableCopying, OFSerialization>
{
	OFString *_scheme, *_host;
	uint16_t _port;
	OFString *_Nullable _user, *_Nullable _password, *_path;
	OFString *_Nullable _parameters, *_Nullable _query;
	OFString *_Nullable _fragment;
}

/*!
 * The scheme part of the URL.
 */
@property (readonly, nonatomic, copy) OFString *scheme;

Modified src/OFURL.m from [114ec293ed] to [2082375f0b].

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
				_user = [[OFString alloc]
				    initWithUTF8String: UTF8String];

			UTF8String = tmp2;
		}

		if ((tmp2 = strchr(UTF8String, ':')) != NULL) {
			void *pool;
			OFString *portString;

			*tmp2 = '\0';
			tmp2++;

			_host = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			pool = objc_autoreleasePoolPush();
			portString = [OFString stringWithUTF8String: tmp2];

			if ([portString decimalValue] > 65535)
				@throw [OFInvalidFormatException exception];

			_port = [portString decimalValue];

			objc_autoreleasePoolPop(pool);
		} else {
			_host = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			if ([_scheme isEqual: @"http"])
				_port = 80;
			else if ([_scheme isEqual: @"https"])







|








|







|







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
				_user = [[OFString alloc]
				    initWithUTF8String: UTF8String];

			UTF8String = tmp2;
		}

		if ((tmp2 = strchr(UTF8String, ':')) != NULL) {
			void *pool2;
			OFString *portString;

			*tmp2 = '\0';
			tmp2++;

			_host = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			pool2 = objc_autoreleasePoolPush();
			portString = [OFString stringWithUTF8String: tmp2];

			if ([portString decimalValue] > 65535)
				@throw [OFInvalidFormatException exception];

			_port = [portString decimalValue];

			objc_autoreleasePoolPop(pool2);
		} else {
			_host = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			if ([_scheme isEqual: @"http"])
				_port = 80;
			else if ([_scheme isEqual: @"https"])

Modified src/OFXMLAttribute.h from [3dd574a92f] to [30a9d4482b].

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * @class OFXMLAttribute OFXMLAttribute.h ObjFW/OFXMLAttribute.h
 *
 * @brief A representation of an attribute of an XML element as an object.
 */
@interface OFXMLAttribute: OFXMLNode
{
@public
	OFString *_name, *_namespace, *_stringValue;
}

/*!
 * The name of the attribute.
 */
@property (readonly, nonatomic) OFString *name;








|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * @class OFXMLAttribute OFXMLAttribute.h ObjFW/OFXMLAttribute.h
 *
 * @brief A representation of an attribute of an XML element as an object.
 */
@interface OFXMLAttribute: OFXMLNode
{
@public
	OFString *_name, *_Nullable _namespace, *_stringValue;
}

/*!
 * The name of the attribute.
 */
@property (readonly, nonatomic) OFString *name;

Modified src/OFXMLElement.h from [2f9d064e3a] to [f3e2075c5a].

28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
/*!
 * @class OFXMLElement OFXMLElement.h ObjFW/OFXMLElement.h
 *
 * @brief A class which stores an XML element.
 */
@interface OFXMLElement: OFXMLNode
{
	OFString *_name, *_namespace, *_defaultNamespace;
	OFMutableArray OF_GENERIC(OFXMLAttribute *) *_attributes;
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_namespaces;

	OFMutableArray OF_GENERIC(OFXMLNode *) *_children;
}

/*!
 * The name of the element.
 */
@property (nonatomic, copy) OFString *name;








|
|
|
>
|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*!
 * @class OFXMLElement OFXMLElement.h ObjFW/OFXMLElement.h
 *
 * @brief A class which stores an XML element.
 */
@interface OFXMLElement: OFXMLNode
{
	OFString *_name, *_Nullable _namespace, *_Nullable _defaultNamespace;
	OFMutableArray OF_GENERIC(OFXMLAttribute *) *_Nullable _attributes;
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_Nullable
	    _namespaces;
	OFMutableArray OF_GENERIC(OFXMLNode *) *_Nullable _children;
}

/*!
 * The name of the element.
 */
@property (nonatomic, copy) OFString *name;

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

/*!
 * @brief Returns the attribute with the specified name.
 *
 * @param attributeName The name of the attribute
 * @return The attribute with the specified name
 */
- (OFXMLAttribute *)attributeForName: (OFString *)attributeName;

/*!
 * @brief Returns the attribute with the specified name and namespace.
 *
 * @param attributeName The name of the attribute
 * @param attributeNS The namespace of the attribute
 * @return The attribute with the specified name and namespace
 */
- (OFXMLAttribute *)attributeForName: (OFString *)attributeName
			   namespace: (nullable OFString *)attributeNS;

/*!
 * @brief Removes the attribute with the specified name.
 *
 * @param attributeName The name of the attribute
 */
- (void)removeAttributeForName: (OFString *)attributeName;







|








|
|







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

/*!
 * @brief Returns the attribute with the specified name.
 *
 * @param attributeName The name of the attribute
 * @return The attribute with the specified name
 */
- (nullable OFXMLAttribute *)attributeForName: (OFString *)attributeName;

/*!
 * @brief Returns the attribute with the specified name and namespace.
 *
 * @param attributeName The name of the attribute
 * @param attributeNS The namespace of the attribute
 * @return The attribute with the specified name and namespace
 */
- (nullable OFXMLAttribute *)attributeForName: (OFString *)attributeName
				    namespace: (nullable OFString *)attributeNS;

/*!
 * @brief Removes the attribute with the specified name.
 *
 * @param attributeName The name of the attribute
 */
- (void)removeAttributeForName: (OFString *)attributeName;
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428

/*!
 * @brief Returns the first child element with the specified name.
 *
 * @param elementName The name of the element
 * @return The first child element with the specified name
 */
- (OFXMLElement *)elementForName: (OFString *)elementName;

/*!
 * @brief Returns the child elements with the specified name.
 *
 * @param elementName The name of the elements
 * @return The child elements with the specified name
 */
- (OFArray OF_GENERIC(OFXMLElement *) *)elementsForName:
    (OFString *)elementName;

/*!
 * @brief Returns the first child element with the specified name and namespace.
 *
 * @param elementName The name of the element
 * @param elementNS The namespace of the element
 * @return The first child element with the specified name and namespace
 */
- (OFXMLElement *)elementForName: (OFString *)elementName
		       namespace: (nullable OFString *)elementNS;

/*!
 * @brief Returns the child elements with the specified name and namespace.
 *
 * @param elementName The name of the elements
 * @param elementNS The namespace of the elements
 * @return The child elements with the specified name and namespace







|

















|
|







396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429

/*!
 * @brief Returns the first child element with the specified name.
 *
 * @param elementName The name of the element
 * @return The first child element with the specified name
 */
- (nullable OFXMLElement *)elementForName: (OFString *)elementName;

/*!
 * @brief Returns the child elements with the specified name.
 *
 * @param elementName The name of the elements
 * @return The child elements with the specified name
 */
- (OFArray OF_GENERIC(OFXMLElement *) *)elementsForName:
    (OFString *)elementName;

/*!
 * @brief Returns the first child element with the specified name and namespace.
 *
 * @param elementName The name of the element
 * @param elementNS The namespace of the element
 * @return The first child element with the specified name and namespace
 */
- (nullable OFXMLElement *)elementForName: (OFString *)elementName
				namespace: (nullable OFString *)elementNS;

/*!
 * @brief Returns the child elements with the specified name and namespace.
 *
 * @param elementName The name of the elements
 * @param elementNS The namespace of the elements
 * @return The child elements with the specified name and namespace

Modified src/OFXMLElementBuilder.h from [f7df881b5d] to [fb6eb4c1ba].

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
 * It can also be used to build OFXMLElements from parts of the document by
 * first parsing stuff using the OFXMLParser with another delegate and then
 * setting the OFXMLElementBuilder as delegate for the parser.
 */
@interface OFXMLElementBuilder: OFObject <OFXMLParserDelegate>
{
	OFMutableArray OF_GENERIC(OFXMLElement *) *_stack;
	id <OFXMLElementBuilderDelegate> _delegate;
}

/*!
 * The delegate for the OFXMLElementBuilder.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, assign)
    id <OFXMLElementBuilderDelegate> delegate;







|







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
 * It can also be used to build OFXMLElements from parts of the document by
 * first parsing stuff using the OFXMLParser with another delegate and then
 * setting the OFXMLElementBuilder as delegate for the parser.
 */
@interface OFXMLElementBuilder: OFObject <OFXMLParserDelegate>
{
	OFMutableArray OF_GENERIC(OFXMLElement *) *_stack;
	id <OFXMLElementBuilderDelegate> _Nullable _delegate;
}

/*!
 * The delegate for the OFXMLElementBuilder.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, assign)
    id <OFXMLElementBuilderDelegate> delegate;

Modified src/OFXMLParser.h from [66eb0bc029] to [f9d631bcc2].

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
 * it is not known to the callback as well, in which case an exception will be
 * risen.
 *
 * @param parser The parser which found an unknown entity
 * @param entity The name of the entity the XML parser didn't know
 * @return A substitution for the entity or `nil`
 */
-      (OFString *)parser: (OFXMLParser *)parser
  foundUnknownEntityNamed: (OFString *)entity;
@end

/*!
 * @class OFXMLParser OFXMLParser.h ObjFW/OFXMLParser.h
 *
 * @brief An event-based XML parser.
 *
 * OFXMLParser is an event-based XML parser which calls the delegate's callbacks
 * as soon as it finds something, thus suitable for streams as well.
 */
@interface OFXMLParser: OFObject <OFStringXMLUnescapingDelegate>
{
	id <OFXMLParserDelegate> _delegate;
	enum of_xml_parser_state {
		OF_XMLPARSER_IN_BYTE_ORDER_MARK,
		OF_XMLPARSER_OUTSIDE_TAG,
		OF_XMLPARSER_TAG_OPENED,
		OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS,
		OF_XMLPARSER_IN_TAG_NAME,
		OF_XMLPARSER_IN_CLOSE_TAG_NAME,







|
|












|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
 * it is not known to the callback as well, in which case an exception will be
 * risen.
 *
 * @param parser The parser which found an unknown entity
 * @param entity The name of the entity the XML parser didn't know
 * @return A substitution for the entity or `nil`
 */
- (nullable OFString *)parser: (OFXMLParser *)parser
      foundUnknownEntityNamed: (OFString *)entity;
@end

/*!
 * @class OFXMLParser OFXMLParser.h ObjFW/OFXMLParser.h
 *
 * @brief An event-based XML parser.
 *
 * OFXMLParser is an event-based XML parser which calls the delegate's callbacks
 * as soon as it finds something, thus suitable for streams as well.
 */
@interface OFXMLParser: OFObject <OFStringXMLUnescapingDelegate>
{
	id <OFXMLParserDelegate> _Nullable _delegate;
	enum of_xml_parser_state {
		OF_XMLPARSER_IN_BYTE_ORDER_MARK,
		OF_XMLPARSER_OUTSIDE_TAG,
		OF_XMLPARSER_TAG_OPENED,
		OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS,
		OF_XMLPARSER_IN_TAG_NAME,
		OF_XMLPARSER_IN_CLOSE_TAG_NAME,
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
		OF_XMLPARSER_IN_COMMENT_OPENING,
		OF_XMLPARSER_IN_COMMENT_1,
		OF_XMLPARSER_IN_COMMENT_2,
		OF_XMLPARSER_IN_DOCTYPE,
		OF_XMLPARSER_NUM_STATES
	} _state;
	size_t _i, _last;
	const char *_data;
	OFMutableData *_buffer;
	OFString *_name, *_prefix;
	OFMutableArray
	    OF_GENERIC(OFMutableDictionary OF_GENERIC(OFString *, OFString *) *)
	    *_namespaces;
	OFMutableArray OF_GENERIC(OFXMLAttribute *) *_attributes;
	OFString *_attributeName, *_attributePrefix;
	char _delimiter;
	OFMutableArray OF_GENERIC(OFString *) *_previous;
	size_t _level;
	bool _acceptProlog;
	size_t _lineNumber;
	bool _lastCarriageReturn, _finishedParsing;
	of_string_encoding_t _encoding;







|

|




|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
		OF_XMLPARSER_IN_COMMENT_OPENING,
		OF_XMLPARSER_IN_COMMENT_1,
		OF_XMLPARSER_IN_COMMENT_2,
		OF_XMLPARSER_IN_DOCTYPE,
		OF_XMLPARSER_NUM_STATES
	} _state;
	size_t _i, _last;
	const char *_Nullable _data;
	OFMutableData *_buffer;
	OFString *_Nullable _name, *_Nullable _prefix;
	OFMutableArray
	    OF_GENERIC(OFMutableDictionary OF_GENERIC(OFString *, OFString *) *)
	    *_namespaces;
	OFMutableArray OF_GENERIC(OFXMLAttribute *) *_attributes;
	OFString *_Nullable _attributeName, *_Nullable _attributePrefix;
	char _delimiter;
	OFMutableArray OF_GENERIC(OFString *) *_previous;
	size_t _level;
	bool _acceptProlog;
	size_t _lineNumber;
	bool _lastCarriageReturn, _finishedParsing;
	of_string_encoding_t _encoding;

Modified src/OFZIPArchive.h from [b61ed08fb0] to [c1d40e93ed].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@interface OFZIPArchive: OFObject
{
	OFSeekableStream *_stream;
	uint32_t _diskNumber, _centralDirectoryDisk;
	uint64_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries;
	uint64_t _centralDirectorySize;
	int64_t _centralDirectoryOffset;
	OFString *_archiveComment;
	OFMutableArray OF_GENERIC(OFZIPArchiveEntry *) *_entries;
	OFMutableDictionary OF_GENERIC(OFString *, OFZIPArchiveEntry *)
	    *_pathToEntryMap;
	OFStream *_lastReturnedStream;
}

/*!
 * The archive comment.
 */
@property (readonly, nonatomic) OFString *archiveComment;








|



|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@interface OFZIPArchive: OFObject
{
	OFSeekableStream *_stream;
	uint32_t _diskNumber, _centralDirectoryDisk;
	uint64_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries;
	uint64_t _centralDirectorySize;
	int64_t _centralDirectoryOffset;
	OFString *_Nullable _archiveComment;
	OFMutableArray OF_GENERIC(OFZIPArchiveEntry *) *_entries;
	OFMutableDictionary OF_GENERIC(OFString *, OFZIPArchiveEntry *)
	    *_pathToEntryMap;
	OFStream *_Nullable _lastReturnedStream;
}

/*!
 * The archive comment.
 */
@property (readonly, nonatomic) OFString *archiveComment;

Modified src/OFZIPArchive.m from [8c3891b987] to [65a1aa4c22].

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
- initWithStream: (OFStream *)stream;
- (bool)matchesEntry: (OFZIPArchiveEntry *)entry;
@end

@interface OFZIPArchive_FileStream: OFStream
{
	OFStream *_stream, *_decompressedStream;
	OFZIPArchive_LocalFileHeader *_localFileHeader;
	bool _hasDataDescriptor;
	uint64_t _size;
	uint32_t _CRC32;
	bool _atEndOfStream;
}

-  initWithStream: (OFStream *)path
  localFileHeader: (OFZIPArchive_LocalFileHeader *)localFileHeader;
@end

uint32_t
of_zip_archive_read_field32(const uint8_t **data, uint16_t *size)
{
	uint32_t field = 0;








|
<
|





|







69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
- initWithStream: (OFStream *)stream;
- (bool)matchesEntry: (OFZIPArchiveEntry *)entry;
@end

@interface OFZIPArchive_FileStream: OFStream
{
	OFStream *_stream, *_decompressedStream;
	OFZIPArchiveEntry *_entry;

	uint64_t _toRead;
	uint32_t _CRC32;
	bool _atEndOfStream;
}

-  initWithStream: (OFStream *)path
	    entry: (OFZIPArchiveEntry *)localFileHeader;
@end

uint32_t
of_zip_archive_read_field32(const uint8_t **data, uint16_t *size)
{
	uint32_t field = 0;

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370

		@throw [OFUnsupportedVersionException
		    exceptionWithVersion: version];
	}

	_lastReturnedStream = [[OFZIPArchive_FileStream alloc]
	     initWithStream: _stream
	    localFileHeader: localFileHeader];

	objc_autoreleasePoolPop(pool);

	return _lastReturnedStream;
}
@end








|







355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

		@throw [OFUnsupportedVersionException
		    exceptionWithVersion: version];
	}

	_lastReturnedStream = [[OFZIPArchive_FileStream alloc]
	     initWithStream: _stream
		      entry: entry];

	objc_autoreleasePoolPop(pool);

	return _lastReturnedStream;
}
@end

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

	return true;
}
@end

@implementation OFZIPArchive_FileStream
-  initWithStream: (OFStream *)stream
  localFileHeader: (OFZIPArchive_LocalFileHeader *)localFileHeader
{
	self = [super init];

	@try {
		_stream = [stream retain];

		switch (localFileHeader->_compressionMethod) {
		case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE:
			_decompressedStream = [stream retain];
			break;
		case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE:
			_decompressedStream = [[OFInflateStream alloc]
			    initWithStream: stream];
			break;
		case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE64:
			_decompressedStream = [[OFInflate64Stream alloc]
			    initWithStream: stream];
			break;
		default:
			@throw [OFNotImplementedException
			    exceptionWithSelector: _cmd
					   object: self];
		}

		_localFileHeader = [localFileHeader retain];
		_hasDataDescriptor = (localFileHeader->_generalPurposeBitFlag &
		    (1 << 3));
		_size = localFileHeader->_uncompressedSize;
		_CRC32 = ~0;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[self close];


	[_decompressedStream release];
	[_localFileHeader release];

	[super dealloc];
}

- (bool)lowlevelIsAtEndOfStream
{
	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	size_t min, ret;

	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		return 0;

	if (_hasDataDescriptor) {
		if ([_decompressedStream isAtEndOfStream]) {
			uint32_t CRC32;

			_atEndOfStream = true;

			CRC32 = [_stream readLittleEndianInt32];
			if (CRC32 == 0x08074B50)
				CRC32 = [_stream readLittleEndianInt32];

			if (~_CRC32 != CRC32)
				@throw [OFChecksumFailedException exception];

			/*
			 * FIXME: Check (un)compressed length!
			 * (Note: Both are 64 bit if the entry uses ZIP64!)
			 */

			return 0;
		}

		ret = [_decompressedStream readIntoBuffer: buffer
						   length: length];
	} else {
		if (_size == 0) {
			_atEndOfStream = true;

			if (~_CRC32 != _localFileHeader->_CRC32)
				@throw [OFChecksumFailedException exception];

			return 0;
		}

		min = (length < _size ? length : (size_t)_size);
		ret = [_decompressedStream readIntoBuffer: buffer
						   length: min];
		_size -= ret;
	}

	_CRC32 = of_crc32(_CRC32, buffer, ret);

	return ret;
}

- (void)close
{
	[_stream release];
	_stream = nil;

	[super close];
}
@end







|






|

















|
<
<
|













>

|












|







<
<
<
|
<
|
<
<
<

<
<
|
<
<
<
<
|
<
|
<
|
|
|
|
|

<
<
|
|
|
|
<
|
<
<
<
|
<












448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480


481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517



518

519



520


521




522

523

524
525
526
527
528
529


530
531
532
533

534



535

536
537
538
539
540
541
542
543
544
545
546
547

	return true;
}
@end

@implementation OFZIPArchive_FileStream
-  initWithStream: (OFStream *)stream
	    entry: (OFZIPArchiveEntry *)entry
{
	self = [super init];

	@try {
		_stream = [stream retain];

		switch ([entry compressionMethod]) {
		case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE:
			_decompressedStream = [stream retain];
			break;
		case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE:
			_decompressedStream = [[OFInflateStream alloc]
			    initWithStream: stream];
			break;
		case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE64:
			_decompressedStream = [[OFInflate64Stream alloc]
			    initWithStream: stream];
			break;
		default:
			@throw [OFNotImplementedException
			    exceptionWithSelector: _cmd
					   object: self];
		}

		_entry = [entry retain];


		_toRead = [entry uncompressedSize];
		_CRC32 = ~0;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[self close];

	[_stream release];
	[_decompressedStream release];
	[_entry release];

	[super dealloc];
}

- (bool)lowlevelIsAtEndOfStream
{
	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	size_t ret;

	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		return 0;




	if (sizeof(length) >= sizeof(uint64_t) && length > UINT64_MAX)

		@throw [OFOutOfRangeException exception];






	if ((uint64_t)length > _toRead)




		length = (size_t)_toRead;



	ret = [_decompressedStream readIntoBuffer: buffer
					   length: length];

	if (ret == 0)
		_atEndOfStream = true;



	_toRead -= ret;
	_CRC32 = of_crc32(_CRC32, buffer, ret);

	if (_toRead == 0)

		if (~_CRC32 != [_entry CRC32])



			@throw [OFChecksumFailedException exception];


	return ret;
}

- (void)close
{
	[_stream release];
	_stream = nil;

	[super close];
}
@end

Modified src/OFZIPArchiveEntry.h from [0e65bfdec8] to [708bd90b86].

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
{
	uint16_t _versionMadeBy, _minVersionNeeded, _generalPurposeBitFlag;
	uint16_t _compressionMethod;
	uint16_t _lastModifiedFileTime, _lastModifiedFileDate;
	uint32_t _CRC32;
	uint64_t _compressedSize, _uncompressedSize;
	OFString *_fileName;
	OFData *_extraField;
	OFString *_fileComment;
	uint32_t _startDiskNumber;
	uint16_t _internalAttributes;
	uint32_t _versionSpecificAttributes;
	int64_t _localFileHeaderOffset;
}

/*!







|
|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
{
	uint16_t _versionMadeBy, _minVersionNeeded, _generalPurposeBitFlag;
	uint16_t _compressionMethod;
	uint16_t _lastModifiedFileTime, _lastModifiedFileDate;
	uint32_t _CRC32;
	uint64_t _compressedSize, _uncompressedSize;
	OFString *_fileName;
	OFData *_Nullable _extraField;
	OFString *_Nullable _fileComment;
	uint32_t _startDiskNumber;
	uint16_t _internalAttributes;
	uint32_t _versionSpecificAttributes;
	int64_t _localFileHeaderOffset;
}

/*!

Modified src/block.h from [a2c827d522] to [6fd563cf3c].

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#endif
	int flags;
	int reserved;
	void (*invoke)(void *block, ...);
	struct of_block_descriptor_t {
		unsigned long reserved;
		unsigned long size;
		void (*copy_helper)(void *dest, void *src);
		void (*dispose_helper)(void *src);
		const char *signature;
	} *descriptor;
} of_block_literal_t;

#ifdef __cplusplus
extern "C" {
#endif







|
|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#endif
	int flags;
	int reserved;
	void (*invoke)(void *block, ...);
	struct of_block_descriptor_t {
		unsigned long reserved;
		unsigned long size;
		void (*_Nullable copy_helper)(void *dest, void *src);
		void (*_Nullable dispose_helper)(void *src);
		const char *signature;
	} *descriptor;
} of_block_literal_t;

#ifdef __cplusplus
extern "C" {
#endif

Modified src/bridge/OFString+NSObject.m from [f1289a59f8] to [d89258eedd].

14
15
16
17
18
19
20


21
22
23
24
25






26
 * file.
 */

#import <Foundation/NSString.h>

#import "OFString+NSObject.h"



@implementation OFString (NSObject)
- (id)NSObject
{
	return [NSString stringWithUTF8String: [self UTF8String]];
}






@end







>
>



|
|
>
>
>
>
>
>

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 * file.
 */

#import <Foundation/NSString.h>

#import "OFString+NSObject.h"

#import "OFInitializationFailedException.h"

@implementation OFString (NSObject)
- (id)NSObject
{
	NSString *string = [NSString stringWithUTF8String: [self UTF8String]];

	if (string == nil)
		@throw [OFInitializationFailedException
		    exceptionWithClass: [NSString class]];

	return string;
}
@end

Modified src/exceptions/OFMemoryNotPartOfObjectException.h from [aaf3eabd13] to [ebaae357da].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 *	  OFMemoryNotPartOfObjectException.h \
 *	  ObjFW/OFMemoryNotPartOfObjectException.h
 *
 * @brief An exception indicating the given memory is not part of the object.
 */
@interface OFMemoryNotPartOfObjectException: OFException
{
	void *_pointer;
	id _object;
}

/*!
 * A pointer to the memory which is not part of the object.
 */
@property (readonly, nonatomic) void *pointer;

/*!
 * The object which the memory is not part of.
 */
@property (readonly, nonatomic) id object;

+ (instancetype)exception OF_UNAVAILABLE;

/*!
 * @brief Creates a new, autoreleased memory not part of object exception.
 *
 * @param pointer A pointer to the memory that is not part of the object
 * @param object The object which the memory is not part of
 * @return A new, autoreleased memory not part of object exception
 */
+ (instancetype)exceptionWithPointer: (void *)pointer
			      object: (id)object;

- init OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated memory not part of object exception.
 *
 * @param pointer A pointer to the memory that is not part of the object
 * @param object The object which the memory is not part of
 * @return An initialized memory not part of object exception
 */
- initWithPointer: (void *)pointer
	   object: (id)object OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END







|






|















|











|




23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 *	  OFMemoryNotPartOfObjectException.h \
 *	  ObjFW/OFMemoryNotPartOfObjectException.h
 *
 * @brief An exception indicating the given memory is not part of the object.
 */
@interface OFMemoryNotPartOfObjectException: OFException
{
	void *_Nullable _pointer;
	id _object;
}

/*!
 * A pointer to the memory which is not part of the object.
 */
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) void *pointer;

/*!
 * The object which the memory is not part of.
 */
@property (readonly, nonatomic) id object;

+ (instancetype)exception OF_UNAVAILABLE;

/*!
 * @brief Creates a new, autoreleased memory not part of object exception.
 *
 * @param pointer A pointer to the memory that is not part of the object
 * @param object The object which the memory is not part of
 * @return A new, autoreleased memory not part of object exception
 */
+ (instancetype)exceptionWithPointer: (nullable void *)pointer
			      object: (id)object;

- init OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated memory not part of object exception.
 *
 * @param pointer A pointer to the memory that is not part of the object
 * @param object The object which the memory is not part of
 * @return An initialized memory not part of object exception
 */
- initWithPointer: (nullable void *)pointer
	   object: (id)object OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/macros.h from [8a33280748] to [aa4d0729bb].

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
		OF_HASH_ADD(hash, (otherCopy >> 24) & 0xFF);	\
		OF_HASH_ADD(hash, (otherCopy >> 16) & 0xFF);	\
		OF_HASH_ADD(hash, (otherCopy >>  8) & 0xFF);	\
		OF_HASH_ADD(hash, otherCopy & 0xFF);		\
	}

static OF_INLINE bool
of_bitset_isset(uint8_t *storage, size_t index)
{
	return storage[index / 8] & (1 << (index % 8));
}

static OF_INLINE void
of_bitset_set(uint8_t *storage, size_t index)
{
	storage[index / 8] |= (1 << (index % 8));
}

static OF_INLINE void
of_bitset_clear(uint8_t *storage, size_t index)
{
	storage[index / 8] &= ~(1 << (index % 8));
}

static OF_INLINE char *
of_strdup(const char *string)
{
	char *copy;
	size_t length = strlen(string);

	if ((copy = (char *)malloc(length + 1)) == NULL)
		return NULL;

	memcpy(copy, string, length + 1);

	return copy;
}

static OF_INLINE void
of_explicit_memset(void *buffer_, int character, size_t length)
{
	volatile unsigned char *buffer = (volatile unsigned char *)buffer_;

	while (buffer < (unsigned char *)buffer_ + length)
		*buffer++ = character;
}








|





|





|




|
|













|







600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
		OF_HASH_ADD(hash, (otherCopy >> 24) & 0xFF);	\
		OF_HASH_ADD(hash, (otherCopy >> 16) & 0xFF);	\
		OF_HASH_ADD(hash, (otherCopy >>  8) & 0xFF);	\
		OF_HASH_ADD(hash, otherCopy & 0xFF);		\
	}

static OF_INLINE bool
of_bitset_isset(uint8_t *_Nonnull storage, size_t index)
{
	return storage[index / 8] & (1 << (index % 8));
}

static OF_INLINE void
of_bitset_set(uint8_t *_Nonnull storage, size_t index)
{
	storage[index / 8] |= (1 << (index % 8));
}

static OF_INLINE void
of_bitset_clear(uint8_t *_Nonnull storage, size_t index)
{
	storage[index / 8] &= ~(1 << (index % 8));
}

static OF_INLINE char *_Nullable
of_strdup(const char *_Nonnull string)
{
	char *copy;
	size_t length = strlen(string);

	if ((copy = (char *)malloc(length + 1)) == NULL)
		return NULL;

	memcpy(copy, string, length + 1);

	return copy;
}

static OF_INLINE void
of_explicit_memset(void *_Nonnull buffer_, int character, size_t length)
{
	volatile unsigned char *buffer = (volatile unsigned char *)buffer_;

	while (buffer < (unsigned char *)buffer_ + length)
		*buffer++ = character;
}

Modified src/of_asprintf.m from [3e2fecec3f] to [e20ce9de33].

556
557
558
559
560
561
562
563
564


565
566
567
568
569
570
571
572
573
			void *pool = objc_autoreleasePoolPush();
			char *tmp2;

			@try {
				OFMutableString *tmpStr = [OFMutableString
				    stringWithUTF8String: tmp
						  length: tmpLen];
				OFString *decimalPoint =
				    [OFLocalization decimalPoint];


				[tmpStr replaceOccurrencesOfString: decimalPoint
							withString: @"."];
				if ([tmpStr UTF8StringLength] > INT_MAX)
					return false;
				tmpLen = (int)[tmpStr UTF8StringLength];
				tmp2 = malloc(tmpLen);
				memcpy(tmp2, [tmpStr UTF8String], tmpLen);
			} @finally {
				free(tmp);







|

>
>
|
|







556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
			void *pool = objc_autoreleasePoolPush();
			char *tmp2;

			@try {
				OFMutableString *tmpStr = [OFMutableString
				    stringWithUTF8String: tmp
						  length: tmpLen];
				OFString *point =
				    [OFLocalization decimalPoint];
				if (point != nil)
					[tmpStr
					    replaceOccurrencesOfString: point
							    withString: @"."];
				if ([tmpStr UTF8StringLength] > INT_MAX)
					return false;
				tmpLen = (int)[tmpStr UTF8StringLength];
				tmp2 = malloc(tmpLen);
				memcpy(tmp2, [tmpStr UTF8String], tmpLen);
			} @finally {
				free(tmp);

Modified src/runtime/Makefile from [80fa148287] to [34e6bcc419].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
include ../../extra.mk

SUBDIRS = lookup-asm

SHARED_LIB = ${OBJFW_RT_SHARED_LIB}
STATIC_LIB = ${OBJFW_RT_STATIC_LIB}
MORPHOS_LIB = ${OBJFW_RT_MORPHOS_LIB}
LIB_MAJOR = ${OBJFW_RT_LIB_MAJOR}
LIB_MINOR = ${OBJFW_RT_LIB_MINOR}

SRCS = arc.m			\
       category.m		\
       class.m			\
       dtable.m			\






<







1
2
3
4
5
6

7
8
9
10
11
12
13
include ../../extra.mk

SUBDIRS = lookup-asm

SHARED_LIB = ${OBJFW_RT_SHARED_LIB}
STATIC_LIB = ${OBJFW_RT_STATIC_LIB}

LIB_MAJOR = ${OBJFW_RT_LIB_MAJOR}
LIB_MINOR = ${OBJFW_RT_LIB_MINOR}

SRCS = arc.m			\
       category.m		\
       class.m			\
       dtable.m			\
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
SRCS_THREADS = threading.m	\
	       ../threading.m
INCLUDES = ObjFW-RT.h
includesubdir = ObjFW-RT

OBJS_EXTRA = ${LOOKUP_ASM_LOOKUP_ASM_A}
LIB_OBJS_EXTRA = ${LOOKUP_ASM_LOOKUP_ASM_LIB_A}
MORPHOS_LIB_OBJS_EXTRA = morphos-library.o ${LOOKUP_ASM_LOOKUP_ASM_A}

include ../../buildsys.mk

${MORPHOS_LIB}: ppcinline.h
ppcinline.h: ObjFW-RT.fd protos.h
	cvinclude.pl			\
		--root ObjFW_RT		\
		--fd ObjFW-RT.fd	\
		--clib protos.h		\
		--inline $@

CPPFLAGS += -I. -I.. -I../..				\
	    -DOF_COMPILING_OBJFW_RT			\
	    -DOBJFW_RT_LIB_MAJOR=${OBJFW_RT_LIB_MAJOR}	\
	    -DOBJFW_RT_LIB_MINOR=${OBJFW_RT_LIB_MINOR}
LD = ${OBJC}







<



<
<
<
<
<
<
<
<





26
27
28
29
30
31
32

33
34
35








36
37
38
39
40
SRCS_THREADS = threading.m	\
	       ../threading.m
INCLUDES = ObjFW-RT.h
includesubdir = ObjFW-RT

OBJS_EXTRA = ${LOOKUP_ASM_LOOKUP_ASM_A}
LIB_OBJS_EXTRA = ${LOOKUP_ASM_LOOKUP_ASM_LIB_A}


include ../../buildsys.mk









CPPFLAGS += -I. -I.. -I../..				\
	    -DOF_COMPILING_OBJFW_RT			\
	    -DOBJFW_RT_LIB_MAJOR=${OBJFW_RT_LIB_MAJOR}	\
	    -DOBJFW_RT_LIB_MINOR=${OBJFW_RT_LIB_MINOR}
LD = ${OBJC}

Modified src/runtime/ObjFW-RT.h from [8577ac8d70] to [6c5a7458b9].

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# endif
#endif

#if !__has_feature(objc_arc) && !defined(__unsafe_unretained)
# define __unsafe_unretained
#endif

#define Nil (Class)0
#define nil (id)0
#define YES (BOOL)1
#define NO  (BOOL)0

typedef struct objc_class *Class;
typedef struct objc_object *id;
typedef const struct objc_selector *SEL;
typedef signed char BOOL;
typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...);
typedef void (*objc_uncaught_exception_handler)(id _Nullable);
typedef void (*objc_enumeration_mutation_handler)(id _Nonnull);

struct objc_class {
	Class _Nonnull isa;
	Class _Nullable superclass;
	const char *_Nonnull name;
	unsigned long version;
	unsigned long info;
	long instance_size;
	struct objc_ivar_list *_Nullable ivars;
	struct objc_method_list *_Nullable methodlist;
	struct objc_dtable *_Nullable dtable;
	Class _Nonnull *_Nullable subclass_list;
	void *_Nullable sibling_class;
	struct objc_protocol_list *_Nullable protocols;
	void *_Nullable gc_object_type;
	unsigned long abi_version;
	int32_t *_Nonnull *_Nullable ivar_offsets;
	struct objc_property_list *_Nullable properties;
};







|
|




















|
|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# endif
#endif

#if !__has_feature(objc_arc) && !defined(__unsafe_unretained)
# define __unsafe_unretained
#endif

#define Nil (Class _Null_unspecified)0
#define nil (id _Null_unspecified)0
#define YES (BOOL)1
#define NO  (BOOL)0

typedef struct objc_class *Class;
typedef struct objc_object *id;
typedef const struct objc_selector *SEL;
typedef signed char BOOL;
typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...);
typedef void (*objc_uncaught_exception_handler)(id _Nullable);
typedef void (*objc_enumeration_mutation_handler)(id _Nonnull);

struct objc_class {
	Class _Nonnull isa;
	Class _Nullable superclass;
	const char *_Nonnull name;
	unsigned long version;
	unsigned long info;
	long instance_size;
	struct objc_ivar_list *_Nullable ivars;
	struct objc_method_list *_Nullable methodlist;
	struct objc_dtable *_Nonnull dtable;
	Class _Nullable *_Nullable subclass_list;
	void *_Nullable sibling_class;
	struct objc_protocol_list *_Nullable protocols;
	void *_Nullable gc_object_type;
	unsigned long abi_version;
	int32_t *_Nonnull *_Nullable ivar_offsets;
	struct objc_property_list *_Nullable properties;
};
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

struct objc_protocol_list {
	struct objc_protocol_list *_Nullable next;
	long count;
	Protocol *__unsafe_unretained _Nonnull list[1];
};

#if 1 /* !defined(__MORPHOS__) || defined(OF_COMPILING_OBJFW_RT) */
# ifdef __cplusplus
extern "C" {
# endif
extern SEL _Nonnull sel_registerName(const char *_Nonnull);
extern const char *_Nonnull sel_getName(SEL _Nonnull);
extern bool sel_isEqual(SEL _Nonnull, SEL _Nonnull);
extern Class _Nonnull objc_allocateClassPair(Class _Nullable,
    const char *_Nonnull, size_t);
extern void objc_registerClassPair(Class _Nonnull);
extern unsigned int objc_getClassList(Class _Nonnull *_Nullable, unsigned int);







<
|

|







195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211

struct objc_protocol_list {
	struct objc_protocol_list *_Nullable next;
	long count;
	Protocol *__unsafe_unretained _Nonnull list[1];
};


#ifdef __cplusplus
extern "C" {
#endif
extern SEL _Nonnull sel_registerName(const char *_Nonnull);
extern const char *_Nonnull sel_getName(SEL _Nonnull);
extern bool sel_isEqual(SEL _Nonnull, SEL _Nonnull);
extern Class _Nonnull objc_allocateClassPair(Class _Nullable,
    const char *_Nonnull, size_t);
extern void objc_registerClassPair(Class _Nonnull);
extern unsigned int objc_getClassList(Class _Nonnull *_Nullable, unsigned int);
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
    SEL _Nonnull);
extern bool class_addMethod(Class _Nonnull, SEL _Nonnull, IMP _Nonnull,
    const char *_Nullable);
extern IMP _Nullable class_replaceMethod(Class _Nonnull, SEL _Nonnull,
    IMP _Nonnull, const char *_Nullable);
extern Class _Nullable object_getClass(id _Nullable);
extern Class _Nullable object_setClass(id _Nullable, Class _Nonnull);
extern const char *_Nonnull object_getClassName(id _Nullable);
extern const char *_Nonnull protocol_getName(Protocol *_Nonnull);
extern bool protocol_isEqual(Protocol *_Nonnull, Protocol *_Nonnull);
extern bool protocol_conformsToProtocol(Protocol *_Nonnull, Protocol *_Nonnull);
extern void objc_exit(void);
extern _Nullable objc_uncaught_exception_handler
    objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler _Nullable);
extern void objc_setForwardHandler(IMP _Nullable, IMP _Nullable);
extern void objc_setEnumerationMutationHandler(
    objc_enumeration_mutation_handler _Nullable);
extern void objc_zero_weak_references(id _Nonnull);
# ifdef __cplusplus
}
# endif
#else
# define BOOL EXEC_BOOL
# include <ppcinline/macros.h>
# undef BOOL
# ifdef __cplusplus
extern "C" {
# endif
extern struct Library *ObjFWRTBase;
# ifdef __cplusplus
}
# endif
# include "ppcinline.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Used by the compiler, but can also be called manually.
 *
 * They need to be in the glue code for the MorphOS library.
 *
 * These declarations are also required to prevent Clang's implicit
 * declarations which include __declspec(dllimport) on Windows.







|











<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243


















244
245
246
247
248
249
250
    SEL _Nonnull);
extern bool class_addMethod(Class _Nonnull, SEL _Nonnull, IMP _Nonnull,
    const char *_Nullable);
extern IMP _Nullable class_replaceMethod(Class _Nonnull, SEL _Nonnull,
    IMP _Nonnull, const char *_Nullable);
extern Class _Nullable object_getClass(id _Nullable);
extern Class _Nullable object_setClass(id _Nullable, Class _Nonnull);
extern const char *_Nullable object_getClassName(id _Nullable);
extern const char *_Nonnull protocol_getName(Protocol *_Nonnull);
extern bool protocol_isEqual(Protocol *_Nonnull, Protocol *_Nonnull);
extern bool protocol_conformsToProtocol(Protocol *_Nonnull, Protocol *_Nonnull);
extern void objc_exit(void);
extern _Nullable objc_uncaught_exception_handler
    objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler _Nullable);
extern void objc_setForwardHandler(IMP _Nullable, IMP _Nullable);
extern void objc_setEnumerationMutationHandler(
    objc_enumeration_mutation_handler _Nullable);
extern void objc_zero_weak_references(id _Nonnull);




















/*
 * Used by the compiler, but can also be called manually.
 *
 * They need to be in the glue code for the MorphOS library.
 *
 * These declarations are also required to prevent Clang's implicit
 * declarations which include __declspec(dllimport) on Windows.

Modified src/runtime/lookup-asm/lookup-asm-sparc64-elf.S from [03722104be] to [44cfec8a34].

48
49
50
51
52
53
54
55
56
57
58
59





60
61
62
63
64
65
66
#ifdef OF_SELUID24
	ldx	[%o2 + %o3], %o2
#endif
	ldx	[%o2 + %o4], %o2
	ldx	[%o2 + %o5], %o2

	cmp	%o2, 0
	be,pn	%xcc, \not_found
	 nop

	retl
	 mov	%o2, %o0





.type \name, %function
.size \name, .-\name
.endm

.macro generate_lookup_super name lookup
\name:
	mov	%o0, %o2







|




>
>
>
>
>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifdef OF_SELUID24
	ldx	[%o2 + %o3], %o2
#endif
	ldx	[%o2 + %o4], %o2
	ldx	[%o2 + %o5], %o2

	cmp	%o2, 0
	be,pn	%xcc, 0f
	 nop

	retl
	 mov	%o2, %o0

0:
	mov	%o7, %g1
	call	\not_found
	 mov	%g1, %o7
.type \name, %function
.size \name, .-\name
.endm

.macro generate_lookup_super name lookup
\name:
	mov	%o0, %o2

Deleted src/runtime/morphos-library.m version [90367d03a6].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
 *   Jonathan Schleifer <js@heap.zone>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "ObjFW-RT.h"
#import "macros.h"

#define BOOL EXEC_BOOL
#include <dos/dos.h>
#include <emul/emulregs.h>
#include <exec/execbase.h>
#include <exec/nodes.h>
#include <exec/resident.h>
#include <exec/types.h>
#include <proto/exec.h>
#undef BOOL

struct ObjFWRTBase {
	struct Library library;
	BPTR seg_list;
};

/* Forward declarations for all functions in the func_table */
static struct Library *lib_init(struct ObjFWRTBase *base, BPTR seg_list,
    struct ExecBase *exec_base);
static struct Library *lib_open(void);
static BPTR lib_close(void);
static BPTR lib_expunge(void);
static void lib_null(void);
void objc_set_exit(void OF_NO_RETURN_FUNC (*exit_fn_)(int status));

static ULONG func_table[] = {
	FUNCARRAY_BEGIN,
	FUNCARRAY_32BIT_NATIVE,
	(ULONG)lib_open,
	(ULONG)lib_close,
	(ULONG)lib_expunge,
	(ULONG)lib_null,
	-1,
	FUNCARRAY_32BIT_SYSTEMV,
	/* Functions for the glue code */
	(ULONG)objc_set_exit,
	/* Used by the compiler - these need glue code */
	(ULONG)__objc_exec_class,
	(ULONG)objc_msg_lookup,
	(ULONG)objc_msg_lookup_stret,
	(ULONG)objc_msg_lookup_super,
	(ULONG)objc_msg_lookup_super_stret,
	(ULONG)objc_lookUpClass,
	(ULONG)objc_getClass,
	(ULONG)objc_getRequiredClass,
	(ULONG)objc_exception_throw,
	(ULONG)objc_sync_enter,
	(ULONG)objc_sync_exit,
	(ULONG)objc_getProperty,
	(ULONG)objc_setProperty,
	(ULONG)objc_getPropertyStruct,
	(ULONG)objc_setPropertyStruct,
	(ULONG)objc_enumerationMutation,
	/* Functions declared in ObjFW-RT.h */
	(ULONG)sel_registerName,
	(ULONG)sel_getName,
	(ULONG)sel_isEqual,
	(ULONG)objc_allocateClassPair,
	(ULONG)objc_registerClassPair,
	(ULONG)objc_getClassList,
	(ULONG)objc_copyClassList,
	(ULONG)class_isMetaClass,
	(ULONG)class_getName,
	(ULONG)class_getSuperclass,
	(ULONG)class_getInstanceSize,
	(ULONG)class_respondsToSelector,
	(ULONG)class_conformsToProtocol,
	(ULONG)class_getMethodImplementation,
	(ULONG)class_getMethodImplementation_stret,
	(ULONG)class_getMethodTypeEncoding,
	(ULONG)class_addMethod,
	(ULONG)class_replaceMethod,
	(ULONG)object_getClass,
	(ULONG)object_setClass,
	(ULONG)object_getClassName,
	(ULONG)protocol_getName,
	(ULONG)protocol_isEqual,
	(ULONG)protocol_conformsToProtocol,
	(ULONG)objc_exit,
	(ULONG)objc_setUncaughtExceptionHandler,
	(ULONG)objc_setForwardHandler,
	(ULONG)objc_setEnumerationMutationHandler,
	(ULONG)objc_zero_weak_references,
	-1,
	FUNCARRAY_END
};

static struct Library *lib_init(struct ObjFWRTBase *base, BPTR seg_list,
    struct ExecBase *exec_base);

static struct {
	LONG struct_size;
	ULONG *func_table;
	void *data_table;
	struct Library *(*init_func)(struct ObjFWRTBase *base, BPTR seg_list,
	    struct ExecBase *exec_base);
} init_table = {
	.struct_size = sizeof(struct ObjFWRTBase),
	func_table,
	NULL,
	lib_init
};

static struct Resident resident = {
	.rt_MatchWord = RTC_MATCHWORD,
	.rt_MatchTag = &resident,
	.rt_EndSkip = &resident + 1,
	.rt_Flags = RTF_AUTOINIT | RTF_PPC,
	.rt_Version = OBJFW_RT_LIB_MAJOR * 10 + OBJFW_RT_LIB_MINOR,
	.rt_Type = NT_LIBRARY,
	.rt_Pri = 0,
	.rt_Name = (char *)"objfw-rt.library",
	.rt_IdString = (char *)"ObjFW-RT " PACKAGE_VERSION
	    " \xA9 2008-2017 Jonathan Schleifer",
	.rt_Init = &init_table
};

/* Magic required to make this a MorphOS binary */
const ULONG __abox__ = 1;

/* Global variables needed by libnix */
int ThisRequiresConstructorHandling;
struct ExecBase *SysBase;
void *libnix_mempool;

/* Functions passed in from the glue linklib */
static void OF_NO_RETURN_FUNC (*exit_fn)(int status);

void OF_NO_RETURN_FUNC
exit(int status)
{
	exit_fn(status);
}

void
objc_set_exit(void OF_NO_RETURN_FUNC (*exit_fn_)(int status))
{
	exit_fn = exit_fn_;
}

/* Standard library functions */
static struct Library *lib_init(struct ObjFWRTBase *base, BPTR seg_list,
    struct ExecBase *exec_base)
{
	SysBase = exec_base;

	base->seg_list = seg_list;

	return &base->library;
}

static struct Library *
lib_open(void)
{
	struct ObjFWRTBase *base = (struct ObjFWRTBase *)REG_A6;

	base->library.lib_OpenCnt++;
	base->library.lib_Flags &= ~LIBF_DELEXP;

	return &base->library;
}

static BPTR
expunge(struct ObjFWRTBase *base)
{
	/* Still in use - set delayed expunge flag and refuse to expunge */
	if (base->library.lib_OpenCnt > 0) {
		base->library.lib_Flags |= LIBF_DELEXP;
		return 0;
	}

	Remove(&base->library.lib_Node);
	FreeMem((char *)base - base->library.lib_NegSize,
	    base->library.lib_NegSize + base->library.lib_PosSize);

	return base->seg_list;
}

static BPTR
lib_close(void)
{
	struct ObjFWRTBase *base = (struct ObjFWRTBase *)REG_A6;

	/* Not used anymore and delayed expunge flag set -> expunge */
	if (--base->library.lib_OpenCnt == 0 &&
	    (base->library.lib_Flags & LIBF_DELEXP))
		return expunge(base);

	return 0;
}

static BPTR
lib_expunge(void)
{
	return expunge((struct ObjFWRTBase *)REG_A6);
}

static void
lib_null(void)
{
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































Modified src/threading.h from [44065a1e75] to [46db014c33].

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# error of_thread_is_current not implemented!
# error of_thread_current not implemented!
#endif

extern bool of_thread_attr_init(of_thread_attr_t *attr);
extern bool of_thread_new(of_thread_t *thread, void (*function)(id), id object,
    const of_thread_attr_t *attr);
extern void of_thread_set_name(of_thread_t thread, const char *name);
extern bool of_thread_join(of_thread_t thread);
extern bool of_thread_detach(of_thread_t thread);
extern void OF_NO_RETURN_FUNC of_thread_exit(void);
extern void of_once(of_once_t *control, void (*func)(void));
extern bool of_tlskey_new(of_tlskey_t *key);
extern bool of_tlskey_free(of_tlskey_t key);
extern bool of_mutex_new(of_mutex_t *mutex);







|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# error of_thread_is_current not implemented!
# error of_thread_current not implemented!
#endif

extern bool of_thread_attr_init(of_thread_attr_t *attr);
extern bool of_thread_new(of_thread_t *thread, void (*function)(id), id object,
    const of_thread_attr_t *attr);
extern void of_thread_set_name(const char *name);
extern bool of_thread_join(of_thread_t thread);
extern bool of_thread_detach(of_thread_t thread);
extern void OF_NO_RETURN_FUNC of_thread_exit(void);
extern void of_once(of_once_t *control, void (*func)(void));
extern bool of_tlskey_new(of_tlskey_t *key);
extern bool of_tlskey_free(of_tlskey_t key);
extern bool of_mutex_new(of_mutex_t *mutex);

Modified src/threading_pthread.m from [9d56adf88b] to [7c690c290a].

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
{
	pthread_exit(NULL);

	OF_UNREACHABLE
}

void
of_thread_set_name(of_thread_t thread, const char *name)
{
#if defined(OF_HAIKU)
	rename_thread(get_pthread_thread_id(thread), name);
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
	pthread_set_name_np(pthread_self(), name);
#elif defined(HAVE_PTHREAD_SETNAME_NP)
# if defined(OF_MACOS) || defined(OF_IOS)
	pthread_setname_np(name);
# elif defined(__GLIBC__)
	char buffer[16];







|


|







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
{
	pthread_exit(NULL);

	OF_UNREACHABLE
}

void
of_thread_set_name(const char *name)
{
#if defined(OF_HAIKU)
	rename_thread(find_thread(NULL), name);
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
	pthread_set_name_np(pthread_self(), name);
#elif defined(HAVE_PTHREAD_SETNAME_NP)
# if defined(OF_MACOS) || defined(OF_IOS)
	pthread_setname_np(name);
# elif defined(__GLIBC__)
	char buffer[16];

Modified src/threading_winapi.m from [f624bdcb51] to [5f1546849f].

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
{
	ExitThread(0);

	OF_UNREACHABLE
}

void
of_thread_set_name(of_thread_t thread, const char *name)
{
}

bool
of_tlskey_new(of_tlskey_t *key)
{
	return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES);







|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
{
	ExitThread(0);

	OF_UNREACHABLE
}

void
of_thread_set_name(const char *name)
{
}

bool
of_tlskey_new(of_tlskey_t *key)
{
	return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES);

Modified tests/OFArrayTests.m from [b0ab3f0686] to [bbcc951492].

349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

	TEST(@"Detection of mutation during Fast Enumeration", ok)

	[m[0] removeLastObject];

#ifdef OF_HAVE_BLOCKS
	{
		__block bool ok = true;
		__block size_t count = 0;
		OFArray *cmp = a[0];
		OFMutableArray *a2;

		m[0] = [[a[0] mutableCopy] autorelease];
		[m[0] enumerateObjectsUsingBlock:
		    ^ (id obj, size_t idx, bool *stop) {
			    count++;
			    if (![obj isEqual: [cmp objectAtIndex: idx]])
				    ok = false;
		}];

		if (count != [cmp count])
			ok = false;

		TEST(@"Enumeration using blocks", ok)

		ok = false;
		a2 = m[0];
		@try {
			[a2 enumerateObjectsUsingBlock:
			    ^ (id obj, size_t idx, bool *stop) {
				[a2 removeObjectAtIndex: idx];
			}];
		} @catch (OFEnumerationMutationException *e) {
			ok = true;
		} @catch (OFOutOfRangeException *e) {
			/*
			 * Out of bounds access due to enumeration not being
			 * detected.
			 */
		}

		TEST(@"Detection of mutation during enumeration using blocks",
		    ok)
	}

	TEST(@"-[replaceObjectsUsingBlock:]",
	    R([m[0] replaceObjectsUsingBlock: ^ id (id obj, size_t idx) {
		switch (idx) {
		case 0:
			return @"foo";
		case 1:
			return @"bar";
		}

		return nil;
		}]) && [[m[0] description] isEqual: @"(\n\tfoo,\n\tbar\n)"])

	TEST(@"-[mappedArrayUsingBlock:]",
	    [[[m[0] mappedArrayUsingBlock: ^ id (id obj, size_t idx) {
		switch (idx) {
		case 0:
			return @"foobar";
		case 1:
			return @"qux";
		}

		return nil;
	    }] description] isEqual: @"(\n\tfoobar,\n\tqux\n)"])

	TEST(@"-[filteredArrayUsingBlock:]",
	   [[[m[0] filteredArrayUsingBlock: ^ bool (id obj, size_t idx) {
		return [obj isEqual: @"foo"];
	    }] description] isEqual: @"(\n\tfoo\n)"])

	TEST(@"-[foldUsingBlock:]",
	    [[arrayClass arrayWithObjects: [OFMutableString string], @"foo",
	    @"bar", @"baz", nil] foldUsingBlock: ^ id (id left, id right) {
		[left appendString: right];
		return left;







|






|

|
|



|

|

|



|



|








|



|











|











|
|







349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

	TEST(@"Detection of mutation during Fast Enumeration", ok)

	[m[0] removeLastObject];

#ifdef OF_HAVE_BLOCKS
	{
		__block bool blockOk = true;
		__block size_t count = 0;
		OFArray *cmp = a[0];
		OFMutableArray *a2;

		m[0] = [[a[0] mutableCopy] autorelease];
		[m[0] enumerateObjectsUsingBlock:
		    ^ (id object, size_t idx, bool *stop) {
			    count++;
			    if (![object isEqual: [cmp objectAtIndex: idx]])
				    blockOk = false;
		}];

		if (count != [cmp count])
			blockOk = false;

		TEST(@"Enumeration using blocks", blockOk)

		blockOk = false;
		a2 = m[0];
		@try {
			[a2 enumerateObjectsUsingBlock:
			    ^ (id object, size_t idx, bool *stop) {
				[a2 removeObjectAtIndex: idx];
			}];
		} @catch (OFEnumerationMutationException *e) {
			blockOk = true;
		} @catch (OFOutOfRangeException *e) {
			/*
			 * Out of bounds access due to enumeration not being
			 * detected.
			 */
		}

		TEST(@"Detection of mutation during enumeration using blocks",
		    blockOk)
	}

	TEST(@"-[replaceObjectsUsingBlock:]",
	    R([m[0] replaceObjectsUsingBlock: ^ id (id object, size_t idx) {
		switch (idx) {
		case 0:
			return @"foo";
		case 1:
			return @"bar";
		}

		return nil;
		}]) && [[m[0] description] isEqual: @"(\n\tfoo,\n\tbar\n)"])

	TEST(@"-[mappedArrayUsingBlock:]",
	    [[[m[0] mappedArrayUsingBlock: ^ id (id object, size_t idx) {
		switch (idx) {
		case 0:
			return @"foobar";
		case 1:
			return @"qux";
		}

		return nil;
	    }] description] isEqual: @"(\n\tfoobar,\n\tqux\n)"])

	TEST(@"-[filteredArrayUsingBlock:]",
	    [[[m[0] filteredArrayUsingBlock: ^ bool (id object, size_t idx) {
		return [object isEqual: @"foo"];
	    }] description] isEqual: @"(\n\tfoo\n)"])

	TEST(@"-[foldUsingBlock:]",
	    [[arrayClass arrayWithObjects: [OFMutableString string], @"foo",
	    @"bar", @"baz", nil] foldUsingBlock: ^ id (id left, id right) {
		[left appendString: right];
		return left;

Modified tests/OFBlockTests.m from [b51076c2c2] to [57afcae22d].

67
68
69
70
71
72
73





74
75
76

77
78
79
80
81
82
83
	void (^m)(void);
	int (^v)(void);

	TEST(@"Class of stack block",
	    (Class)&_NSConcreteStackBlock == objc_getClass("OFStackBlock") &&
	    [s isKindOfClass: [OFBlock class]])






	TEST(@"Class of global block",
	    (Class)&_NSConcreteGlobalBlock == objc_getClass("OFGlobalBlock") &&
	    [g isKindOfClass: [OFBlock class]])


	TEST(@"Class of a malloc block",
	    (Class)&_NSConcreteMallocBlock == objc_getClass("OFMallocBlock"))

	TEST(@"Copying a stack block",
	    (m = [[s copy] autorelease]) &&
	    [m class] == objc_getClass("OFMallocBlock") &&







>
>
>
>
>



>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	void (^m)(void);
	int (^v)(void);

	TEST(@"Class of stack block",
	    (Class)&_NSConcreteStackBlock == objc_getClass("OFStackBlock") &&
	    [s isKindOfClass: [OFBlock class]])

#if !defined(OF_WINDOWS) || !defined(__clang__)
	/*
	 * Causes a linker error on Windows with Clang when compiling as a
	 * static library. This is a bug in Clang.
	 */
	TEST(@"Class of global block",
	    (Class)&_NSConcreteGlobalBlock == objc_getClass("OFGlobalBlock") &&
	    [g isKindOfClass: [OFBlock class]])
#endif

	TEST(@"Class of a malloc block",
	    (Class)&_NSConcreteMallocBlock == objc_getClass("OFMallocBlock"))

	TEST(@"Copying a stack block",
	    (m = [[s copy] autorelease]) &&
	    [m class] == objc_getClass("OFMallocBlock") &&

Modified tests/OFDictionaryTests.m from [76bc88ef2a] to [f2dd61fdb9].

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
	TEST(@"-[stringByURLEncoding]",
	    [[[OFDictionary dictionaryWithKeysAndObjects: @"foo", @"bar",
							  @"q&x", @"q=x", nil]
	    stringByURLEncoding] isEqual: @"q%26x=q%3Dx&foo=bar"])

#ifdef OF_HAVE_BLOCKS
	{
		__block size_t i = 0;
		__block bool ok = true;

		[mutDict enumerateKeysAndObjectsUsingBlock:
		    ^ (id key, id obj, bool *stop) {
			if (i > 1 || ![key isEqual: keys[i]]) {
				ok = false;
				*stop = true;
				return;
			}

			[mutDict setObject: [mutDict objectForKey: key]
				    forKey: key];
			i++;
		}];

		TEST(@"Enumeration using blocks", ok)

		ok = false;
		@try {
			[mutDict enumerateKeysAndObjectsUsingBlock:
			    ^ (id key, id obj, bool *stop) {
				[mutDict setObject: @""
					    forKey: @""];
			}];
		} @catch (OFEnumerationMutationException *e) {
			ok = true;
		}

		TEST(@"Detection of mutation during enumeration using blocks",
		    ok)

		[mutDict removeObjectForKey: @""];
	}

	TEST(@"-[replaceObjectsUsingBlock:]",
	    R([mutDict replaceObjectsUsingBlock: ^ id (id key, id obj) {
		if ([key isEqual: keys[0]])
			return @"value_1";
		if ([key isEqual: keys[1]])
			return @"value_2";

		return nil;
	    }]) && [[mutDict objectForKey: keys[0]] isEqual: @"value_1"] &&
	    [[mutDict objectForKey: keys[1]] isEqual: @"value_2"])

	TEST(@"-[mappedDictionaryUsingBlock:]",
	    [[[mutDict mappedDictionaryUsingBlock: ^ id (id key, id obj) {
		if ([key isEqual: keys[0]])
			return @"val1";
		if ([key isEqual: keys[1]])
			return @"val2";

		return nil;
	    }] description] isEqual: @"{\n\tkey1 = val1;\n\tkey2 = val2;\n}"])

	TEST(@"-[filteredDictionaryUsingBlock:]",
	    [[[mutDict filteredDictionaryUsingBlock: ^ bool (id key, id obj) {

		return [key isEqual: keys[0]];
	    }] description] isEqual: @"{\n\tkey1 = value_1;\n}"])
#endif

	TEST(@"-[count]", [mutDict count] == 2)

	TEST(@"+[dictionaryWithKeysAndObjects:]",







|
|


|
|
|






|


|

|


|




|



|





|










|









|
>







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
	TEST(@"-[stringByURLEncoding]",
	    [[[OFDictionary dictionaryWithKeysAndObjects: @"foo", @"bar",
							  @"q&x", @"q=x", nil]
	    stringByURLEncoding] isEqual: @"q%26x=q%3Dx&foo=bar"])

#ifdef OF_HAVE_BLOCKS
	{
		__block size_t j = 0;
		__block bool blockOk = true;

		[mutDict enumerateKeysAndObjectsUsingBlock:
		    ^ (id key, id object, bool *stop) {
			if (j > 1 || ![key isEqual: keys[j]]) {
				blockOk = false;
				*stop = true;
				return;
			}

			[mutDict setObject: [mutDict objectForKey: key]
				    forKey: key];
			j++;
		}];

		TEST(@"Enumeration using blocks", blockOk)

		blockOk = false;
		@try {
			[mutDict enumerateKeysAndObjectsUsingBlock:
			    ^ (id key, id object, bool *stop) {
				[mutDict setObject: @""
					    forKey: @""];
			}];
		} @catch (OFEnumerationMutationException *e) {
			blockOk = true;
		}

		TEST(@"Detection of mutation during enumeration using blocks",
		    blockOk)

		[mutDict removeObjectForKey: @""];
	}

	TEST(@"-[replaceObjectsUsingBlock:]",
	    R([mutDict replaceObjectsUsingBlock: ^ id (id key, id object) {
		if ([key isEqual: keys[0]])
			return @"value_1";
		if ([key isEqual: keys[1]])
			return @"value_2";

		return nil;
	    }]) && [[mutDict objectForKey: keys[0]] isEqual: @"value_1"] &&
	    [[mutDict objectForKey: keys[1]] isEqual: @"value_2"])

	TEST(@"-[mappedDictionaryUsingBlock:]",
	    [[[mutDict mappedDictionaryUsingBlock: ^ id (id key, id object) {
		if ([key isEqual: keys[0]])
			return @"val1";
		if ([key isEqual: keys[1]])
			return @"val2";

		return nil;
	    }] description] isEqual: @"{\n\tkey1 = val1;\n\tkey2 = val2;\n}"])

	TEST(@"-[filteredDictionaryUsingBlock:]",
	    [[[mutDict filteredDictionaryUsingBlock:
	    ^ bool (id key, id object) {
		return [key isEqual: keys[0]];
	    }] description] isEqual: @"{\n\tkey1 = value_1;\n}"])
#endif

	TEST(@"-[count]", [mutDict count] == 2)

	TEST(@"+[dictionaryWithKeysAndObjects:]",

Modified tests/OFKernelEventObserverTests.m from [f2b6e225cb] to [6f6df4db2e].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33



34
35
36
37
38
39
40
41
42

#import "OFKernelEventObserver.h"
#import "OFString.h"
#import "OFDate.h"
#import "OFTCPSocket.h"
#import "OFAutoreleasePool.h"

#if defined(HAVE_SYS_SELECT_H) || defined(OF_WINDOWS)
# import "OFKernelEventObserver_select.h"
#endif
#if defined(HAVE_POLL_H) || defined(OF_WII)
# import "OFKernelEventObserver_poll.h"
#endif
#ifdef HAVE_EPOLL
# import "OFKernelEventObserver_epoll.h"
#endif



#ifdef HAVE_KQUEUE
# import "OFKernelEventObserver_kqueue.h"
#endif

#import "TestsAppDelegate.h"

#define EXPECTED_EVENTS 3

static OFString *module;







<
<
|
<
|




>
>
>
|
|







18
19
20
21
22
23
24


25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#import "OFKernelEventObserver.h"
#import "OFString.h"
#import "OFDate.h"
#import "OFTCPSocket.h"
#import "OFAutoreleasePool.h"



#ifdef HAVE_KQUEUE

# import "OFKernelEventObserver_kqueue.h"
#endif
#ifdef HAVE_EPOLL
# import "OFKernelEventObserver_epoll.h"
#endif
#ifdef HAVE_POLL
# import "OFKernelEventObserver_poll.h"
#endif
#ifdef HAVE_SELECT
# import "OFKernelEventObserver_select.h"
#endif

#import "TestsAppDelegate.h"

#define EXPECTED_EVENTS 3

static OFString *module;
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220


221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
	}
}
@end

@implementation TestsAppDelegate (OFKernelEventObserverTests)
- (void)kernelEventObserverTestsWithClass: (Class)class
{

	ObserverTest *test;

	module = [class className];
	test = [[[ObserverTest alloc]
	    initWithTestsAppDelegate: self] autorelease];

	TEST(@"+[observer]",
	    (test->_observer = [OFKernelEventObserver observer]))
	[test->_observer setDelegate: test];

	TEST(@"-[addObjectForReading:]",
	    R([test->_observer addObjectForReading: test->_server]))

	[test run];
	_fails += test->_fails;


}

- (void)kernelEventObserverTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];

#if defined(HAVE_SYS_SELECT_H) || defined(OF_WINDOWS)
	[self kernelEventObserverTestsWithClass:
	    [OFKernelEventObserver_select class]];
#endif

#if defined(HAVE_POLL_H) || defined(OF_WII)
	[self kernelEventObserverTestsWithClass:
	    [OFKernelEventObserver_poll class]];
#endif

#ifdef HAVE_EPOLL
	[self kernelEventObserverTestsWithClass:
	    [OFKernelEventObserver_epoll class]];
#endif

#ifdef HAVE_KQUEUE
	[self kernelEventObserverTestsWithClass:
	    [OFKernelEventObserver_kqueue class]];
#endif

	[pool drain];
}
@end







>






|
<







>
>




<
|
<




|













|
<
<

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226

227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246


247
	}
}
@end

@implementation TestsAppDelegate (OFKernelEventObserverTests)
- (void)kernelEventObserverTestsWithClass: (Class)class
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	ObserverTest *test;

	module = [class className];
	test = [[[ObserverTest alloc]
	    initWithTestsAppDelegate: self] autorelease];

	TEST(@"+[observer]", (test->_observer = [class observer]))

	[test->_observer setDelegate: test];

	TEST(@"-[addObjectForReading:]",
	    R([test->_observer addObjectForReading: test->_server]))

	[test run];
	_fails += test->_fails;

	[pool drain];
}

- (void)kernelEventObserverTests
{

#ifdef HAVE_SELECT

	[self kernelEventObserverTestsWithClass:
	    [OFKernelEventObserver_select class]];
#endif

#ifdef HAVE_POLL
	[self kernelEventObserverTestsWithClass:
	    [OFKernelEventObserver_poll class]];
#endif

#ifdef HAVE_EPOLL
	[self kernelEventObserverTestsWithClass:
	    [OFKernelEventObserver_epoll class]];
#endif

#ifdef HAVE_KQUEUE
	[self kernelEventObserverTestsWithClass:
	    [OFKernelEventObserver_kqueue class]];
#endif
}


@end

Modified tests/OFListTests.m from [3c7e2e133b] to [9cc03e5fa4].

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

	[list prependObject: strings[0]];

	loe = [list firstListObject];
	i = 0;
	ok = true;

	for (OFString *obj in list) {
		if (![obj isEqual: loe->object])
			ok = false;

		loe = loe->next;
		i++;
	}

	if ([list count] != i)
		ok = false;

	TEST(@"Fast Enumeration", ok)

	ok = false;
	@try {
		for (OFString *obj in list) {
			(void)obj;

			[list removeListObject: [list lastListObject]];
		}
	} @catch (OFEnumerationMutationException *e) {
		ok = true;
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok)

	[pool drain];
}
@end







|
|













|
|












123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

	[list prependObject: strings[0]];

	loe = [list firstListObject];
	i = 0;
	ok = true;

	for (OFString *object in list) {
		if (![object isEqual: loe->object])
			ok = false;

		loe = loe->next;
		i++;
	}

	if ([list count] != i)
		ok = false;

	TEST(@"Fast Enumeration", ok)

	ok = false;
	@try {
		for (OFString *object in list) {
			(void)object;

			[list removeListObject: [list lastListObject]];
		}
	} @catch (OFEnumerationMutationException *e) {
		ok = true;
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok)

	[pool drain];
}
@end

Modified tests/OFObjectTests.m from [bb532d1546] to [ba866e7637].

251
252
253
254
255
256
257
258
259
260
261
262
263
	    [m unsignedIntValue] == 80 &&
	    [m unsignedLongValue] == 90 &&
	    [m unsignedLongLongValue] == 100 &&
	    [m floatValue] == 110 &&
	    [m doubleValue] == 120)

	EXPECT_EXCEPTION(@"Catch -[setValue:forKey:] with nil key for scalar",
	    OFInvalidArgumentException, [m setValue: nil
					     forKey: @"intValue"])

	[pool drain];
}
@end







|





251
252
253
254
255
256
257
258
259
260
261
262
263
	    [m unsignedIntValue] == 80 &&
	    [m unsignedLongValue] == 90 &&
	    [m unsignedLongLongValue] == 100 &&
	    [m floatValue] == 110 &&
	    [m doubleValue] == 120)

	EXPECT_EXCEPTION(@"Catch -[setValue:forKey:] with nil key for scalar",
	    OFInvalidArgumentException, [m setValue: (id _Nonnull)nil
					     forKey: @"intValue"])

	[pool drain];
}
@end

Modified utils/ofhttp/OFHTTP.m from [492c8ebbc8] to [92c2a328ea].

830
831
832
833
834
835
836
837
838

839
840
841
842
843
844
845
846
847
		} else
			lengthString =
			    OF_LOCALIZED(@"size_unknown", @"unknown");

		if (_verbose) {
			void *pool = objc_autoreleasePoolPush();
			OFDictionary OF_GENERIC(OFString *, OFString *)
			    *headers = [response headers];
			OFEnumerator *keyEnumerator = [headers keyEnumerator];

			OFEnumerator *objectEnumerator =
			    [headers objectEnumerator];
			OFString *key, *object;

			[of_stdout writeString: @"  "];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"info_name_unaligned",
			    @"Name: %[name]",
			    @"name", fileName)];







|
|
>

|







830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
		} else
			lengthString =
			    OF_LOCALIZED(@"size_unknown", @"unknown");

		if (_verbose) {
			void *pool = objc_autoreleasePoolPush();
			OFDictionary OF_GENERIC(OFString *, OFString *)
			    *responseHeaders = [response headers];
			OFEnumerator *keyEnumerator =
			    [responseHeaders keyEnumerator];
			OFEnumerator *objectEnumerator =
			    [responseHeaders objectEnumerator];
			OFString *key, *object;

			[of_stdout writeString: @"  "];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"info_name_unaligned",
			    @"Name: %[name]",
			    @"name", fileName)];