ObjFW  Check-in [e73c65a849]

Overview
Comment:Rename all symbols marked extern
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | new-naming-convention
Files: files | file ages | folders
SHA3-256: e73c65a849634a10d9d87b66b0a6fd94a83a235da384161540402fb7629cf734
User & Date: js on 2021-04-18 22:56:46
Other Links: branch diff | manifest | tags
Context
2021-04-18
23:18
INVALID_SOCKET -> OFInvalidSocketHandle check-in: 4b587c8874 user: js tags: new-naming-convention
22:56
Rename all symbols marked extern check-in: e73c65a849 user: js tags: new-naming-convention
21:20
Rename everything in OFBlock check-in: 29ccd9b1af user: js tags: new-naming-convention
Changes

Modified README.md from [115f8f54ed] to [c56b6e4a95].

313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327







-
+







    $ objfw-new app MyFirstApp

  This creates a file `MyFirstApp.m`. The `-[applicationDidFinishLaunching]`
  method is called as soon as ObjFW finished all initialization. Use this as
  the entry point to your own code. For example, you could add the following
  line there to create a "Hello World":

    [of_stdout writeLine: @"Hello World!"];
    [OFStdOut writeLine: @"Hello World!"];

  You can compile your new app using `objfw-compile`:

    $ objfw-compile -o MyFirstApp MyFirstApp.m

  `objfw-compile` is a tool that allows building applications and libraries
  using ObjFW without needing a full-blown build system. If you want to use

Modified generators/unicode/TableGenerator.h from [d50b4bdc88] to [bbac35a082].

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
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







-
+





-
+





-
+







@interface TableGenerator: OFObject <OFApplicationDelegate,
    OFHTTPClientDelegate>
{
	OFHTTPClient *_HTTPClient;
	OFUnichar _uppercaseTable[0x110000];
	OFUnichar _lowercaseTable[0x110000];
	OFUnichar _titlecaseTable[0x110000];
	OFUnichar _casefoldingTable[0x110000];
	OFUnichar _caseFoldingTable[0x110000];
	OFString *_decompositionTable[0x110000];
	OFString *_decompositionCompatTable[0x110000];
	char _uppercaseTableUsed[0x1100];
	char _lowercaseTableUsed[0x1100];
	char _titlecaseTableUsed[0x1100];
	char _casefoldingTableUsed[0x1100];
	char _caseFoldingTableUsed[0x1100];
	char _decompositionTableUsed[0x1100];
	char _decompositionCompatTableUsed[0x1100];
	size_t _uppercaseTableSize;
	size_t _lowercaseTableSize;
	size_t _titlecaseTableSize;
	size_t _casefoldingTableSize;
	size_t _caseFoldingTableSize;
	size_t _decompositionTableSize;
	size_t _decompositionCompatTableSize;
	enum {
		STATE_UNICODE_DATA,
		STATE_CASE_FOLDING
	} _state;
}

Modified generators/unicode/TableGenerator.m from [15b00187cf] to [0671e3687a].

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
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







-
+














-
+














-
+
















-
+













-
+







	@try {
		_HTTPClient = [[OFHTTPClient alloc] init];
		_HTTPClient.delegate = self;

		_uppercaseTableSize           = SIZE_MAX;
		_lowercaseTableSize           = SIZE_MAX;
		_titlecaseTableSize           = SIZE_MAX;
		_casefoldingTableSize         = SIZE_MAX;
		_caseFoldingTableSize         = SIZE_MAX;
		_decompositionTableSize       = SIZE_MAX;
		_decompositionCompatTableSize = SIZE_MAX;
	} @catch (id e) {
		@throw e;
		[self release];
	}

	return self;
}

- (void)applicationDidFinishLaunching
{
	OFHTTPRequest *request;

	[of_stdout writeString: @"Downloading UnicodeData.txt…"];
	[OFStdOut writeString: @"Downloading UnicodeData.txt…"];
	_state = STATE_UNICODE_DATA;
	request = [OFHTTPRequest requestWithURL:
	    [OFURL URLWithString: UNICODE_DATA_URL]];
	[_HTTPClient asyncPerformRequest: request];
}

-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response
	  exception: (id)exception
{
	if (exception != nil)
		@throw exception;

	[of_stdout writeLine: @" done"];
	[OFStdOut writeLine: @" done"];

	switch (_state) {
	case STATE_UNICODE_DATA:
		[self parseUnicodeData: response];
		break;
	case STATE_CASE_FOLDING:
		[self parseCaseFolding: response];
		break;
	}
}

- (void)parseUnicodeData: (OFHTTPResponse *)response
{
	OFString *line;
	OFHTTPRequest *request;

	[of_stdout writeString: @"Parsing UnicodeData.txt…"];
	[OFStdOut writeString: @"Parsing UnicodeData.txt…"];

	while ((line = [response readLine]) != nil) {
		void *pool2;
		OFArray OF_GENERIC(OFString *) *components;
		OFUnichar codePoint;

		if (line.length == 0)
			continue;

		pool2 = objc_autoreleasePoolPush();

		components = [line componentsSeparatedByString: @";"];
		if (components.count != 15) {
			of_log(@"Invalid line: %@\n", line);
			OFLog(@"Invalid line: %@\n", line);
			[OFApplication terminateWithStatus: 1];
		}

		codePoint = (OFUnichar)[[components objectAtIndex: 0]
		    unsignedLongLongValueWithBase: 16];

		if (codePoint > 0x10FFFF)
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
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







-
+

-
+










-
+













-
+













-
+





-
+








		objc_autoreleasePoolPop(pool2);
	}

	[self applyDecompositionRecursivelyForTable: _decompositionTable];
	[self applyDecompositionRecursivelyForTable: _decompositionCompatTable];

	[of_stdout writeLine: @" done"];
	[OFStdOut writeLine: @" done"];

	[of_stdout writeString: @"Downloading CaseFolding.txt…"];
	[OFStdOut writeString: @"Downloading CaseFolding.txt…"];
	_state = STATE_CASE_FOLDING;
	request = [OFHTTPRequest requestWithURL:
	    [OFURL URLWithString: CASE_FOLDING_URL]];
	[_HTTPClient asyncPerformRequest: request];
}

- (void)parseCaseFolding: (OFHTTPResponse *)response
{
	OFString *line;

	[of_stdout writeString: @"Parsing CaseFolding.txt…"];
	[OFStdOut writeString: @"Parsing CaseFolding.txt…"];

	while ((line = [response readLine]) != nil) {
		void *pool2;
		OFArray OF_GENERIC(OFString *) *components;
		OFUnichar codePoint;

		if (line.length == 0 || [line hasPrefix: @"#"])
			continue;

		pool2 = objc_autoreleasePoolPush();

		components = [line componentsSeparatedByString: @"; "];
		if (components.count != 4) {
			of_log(@"Invalid line: %s\n", line);
			OFLog(@"Invalid line: %s\n", line);
			[OFApplication terminateWithStatus: 1];
		}

		if (![[components objectAtIndex: 1] isEqual: @"S"] &&
		    ![[components objectAtIndex: 1] isEqual: @"C"])
			continue;

		codePoint = (OFUnichar)[[components objectAtIndex: 0]
		    unsignedLongLongValueWithBase: 16];

		if (codePoint > 0x10FFFF)
			@throw [OFOutOfRangeException exception];

		_casefoldingTable[codePoint] = (OFUnichar)[[components
		_caseFoldingTable[codePoint] = (OFUnichar)[[components
		    objectAtIndex: 2] unsignedLongLongValueWithBase: 16];

		objc_autoreleasePoolPop(pool2);
	}

	[of_stdout writeLine: @" done"];
	[OFStdOut writeLine: @" done"];

	[self writeFiles];
}

- (void)applyDecompositionRecursivelyForTable: (OFString *[0x110000])table
{
	bool done;
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290







-
+







-
+







	} while (!done);
}

- (void)writeFiles
{
	OFURL *URL;

	[of_stdout writeString: @"Writing files…"];
	[OFStdOut writeString: @"Writing files…"];

	URL = [OFURL fileURLWithPath: @"../../src/unicode.m"];
	[self writeTablesToFile: URL.fileSystemRepresentation];

	URL = [OFURL fileURLWithPath: @"../../src/unicode.h"];
	[self writeHeaderToFile: URL.fileSystemRepresentation];

	[of_stdout writeLine: @" done"];
	[OFStdOut writeLine: @" done"];

	[OFApplication terminate];
}

- (void)writeTablesToFile: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
412
413
414
415
416
417
418
419

420
421
422
423
424

425
426

427
428
429


430
431
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
448
449
450
451
452








453
454
455
456
457
458
459
412
413
414
415
416
417
418

419
420
421
422
423

424
425

426
427


428
429
430
431
432
433
434
435
436
437
438

439
440
441
442
443
444








445
446
447
448
449
450
451
452
453
454
455
456
457
458
459







-
+




-
+

-
+

-
-
+
+









-
+





-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+








			[file writeString: @"};\n\n"];

			objc_autoreleasePoolPop(pool2);
		}
	}

	/* Write casefoldingPage%u if it does NOT match lowercasePage%u */
	/* Write caseFoldingPage%u if it does NOT match lowercasePage%u */
	for (OFUnichar i = 0; i < 0x110000; i += 0x100) {
		bool isEmpty = true;

		for (OFUnichar j = i; j < i + 0x100; j++) {
			if (_casefoldingTable[j] != 0) {
			if (_caseFoldingTable[j] != 0) {
				isEmpty = !memcmp(_lowercaseTable + i,
				    _casefoldingTable + i,
				    _caseFoldingTable + i,
				    256 * sizeof(OFUnichar));
				_casefoldingTableSize = i >> 8;
				_casefoldingTableUsed[_casefoldingTableSize] =
				_caseFoldingTableSize = i >> 8;
				_caseFoldingTableUsed[_caseFoldingTableSize] =
				    (isEmpty ? 2 : 1);
				break;
			}
		}

		if (!isEmpty) {
			void *pool2 = objc_autoreleasePoolPush();

			[file writeFormat: @"static const OFUnichar "
					   @"casefoldingPage%u[0x100] = {\n",
					   @"caseFoldingPage%u[0x100] = {\n",
					   i >> 8];

			for (OFUnichar j = i; j < i + 0x100; j += 8)
				[file writeFormat:
				    @"\t%u, %u, %u, %u, %u, %u, %u, %u,\n",
				    _casefoldingTable[j],
				    _casefoldingTable[j + 1],
				    _casefoldingTable[j + 2],
				    _casefoldingTable[j + 3],
				    _casefoldingTable[j + 4],
				    _casefoldingTable[j + 5],
				    _casefoldingTable[j + 6],
				    _casefoldingTable[j + 7]];
				    _caseFoldingTable[j],
				    _caseFoldingTable[j + 1],
				    _caseFoldingTable[j + 2],
				    _caseFoldingTable[j + 3],
				    _caseFoldingTable[j + 4],
				    _caseFoldingTable[j + 5],
				    _caseFoldingTable[j + 6],
				    _caseFoldingTable[j + 7]];

			[file writeString: @"};\n\n"];

			objc_autoreleasePoolPop(pool2);
		}
	}

579
580
581
582
583
584
585
586

587
588
589
590

591
592

593
594
595
596
597
598
599
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
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
676
677
678

679
680

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

700
701

702
703
704
705
706
707
708
579
580
581
582
583
584
585

586
587
588
589

590
591

592
593
594
595
596
597
598
599
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
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
676
677

678
679

680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698

699
700

701
702
703
704
705
706
707
708







-
+



-
+

-
+


















-
+

-
+


















-
+

-
+




















-
+

-
-
+
+

-
-
-
-
+
+
+
+




-
+









-
+

-
+


















-
+

-
+







	/*
	 * Those are currently set to the last index.
	 * But from now on, we need the size.
	 */
	_uppercaseTableSize++;
	_lowercaseTableSize++;
	_titlecaseTableSize++;
	_casefoldingTableSize++;
	_caseFoldingTableSize++;
	_decompositionTableSize++;
	_decompositionCompatTableSize++;

	/* Write of_unicode_uppercase_table */
	/* Write OFUnicodeUppercaseTable */
	[file writeFormat: @"const OFUnichar *const "
			   @"of_unicode_uppercase_table[0x%X] = {\n\t",
			   @"OFUnicodeUppercaseTable[0x%X] = {\n\t",
			   _uppercaseTableSize];

	for (OFUnichar i = 0; i < _uppercaseTableSize; i++) {
		if (_uppercaseTableUsed[i])
			[file writeFormat: @"uppercasePage%u", i];
		else
			[file writeString: @"emptyPage"];

		if (i + 1 < _uppercaseTableSize) {
			if ((i + 1) % 4 == 0)
				[file writeString: @",\n\t"];
			else
				[file writeString: @", "];
		}
	}

	[file writeString: @"\n};\n\n"];

	/* Write of_unicode_lowercase_table */
	/* Write OFUnicodeLowercaseTable */
	[file writeFormat: @"const OFUnichar *const "
			   @"of_unicode_lowercase_table[0x%X] = {\n\t",
			   @"OFUnicodeLowercaseTable[0x%X] = {\n\t",
			   _lowercaseTableSize];

	for (OFUnichar i = 0; i < _lowercaseTableSize; i++) {
		if (_lowercaseTableUsed[i])
			[file writeFormat: @"lowercasePage%u", i];
		else
			[file writeString: @"emptyPage"];

		if (i + 1 < _lowercaseTableSize) {
			if ((i + 1) % 4 == 0)
				[file writeString: @",\n\t"];
			else
				[file writeString: @", "];
		}
	}

	[file writeString: @"\n};\n\n"];

	/* Write of_unicode_titlecase_table */
	/* Write OFUnicodeTitlecaseTable */
	[file writeFormat: @"const OFUnichar *const "
			   @"of_unicode_titlecase_table[0x%X] = {\n\t",
			   @"OFUnicodeTitlecaseTable[0x%X] = {\n\t",
			   _titlecaseTableSize];

	for (OFUnichar i = 0; i < _titlecaseTableSize; i++) {
		if (_titlecaseTableUsed[i] == 1)
			[file writeFormat: @"titlecasePage%u", i];
		else if (_titlecaseTableUsed[i] == 2)
			[file writeFormat: @"uppercasePage%u", i];
		else
			[file writeString: @"emptyPage"];

		if (i + 1 < _titlecaseTableSize) {
			if ((i + 1) % 4 == 0)
				[file writeString: @",\n\t"];
			else
				[file writeString: @", "];
		}
	}

	[file writeString: @"\n};\n\n"];

	/* Write of_unicode_casefolding_table */
	/* Write OFUnicodeCaseFoldingTable */
	[file writeFormat: @"const OFUnichar *const "
			   @"of_unicode_casefolding_table[0x%X] = {\n\t",
			   _casefoldingTableSize];
			   @"OFUnicodeCaseFoldingTable[0x%X] = {\n\t",
			   _caseFoldingTableSize];

	for (OFUnichar i = 0; i < _casefoldingTableSize; i++) {
		if (_casefoldingTableUsed[i] == 1)
			[file writeFormat: @"casefoldingPage%u", i];
		else if (_casefoldingTableUsed[i] == 2)
	for (OFUnichar i = 0; i < _caseFoldingTableSize; i++) {
		if (_caseFoldingTableUsed[i] == 1)
			[file writeFormat: @"caseFoldingPage%u", i];
		else if (_caseFoldingTableUsed[i] == 2)
			[file writeFormat: @"lowercasePage%u", i];
		else
			[file writeString: @"emptyPage"];

		if (i + 1 < _casefoldingTableSize) {
		if (i + 1 < _caseFoldingTableSize) {
			if ((i + 1) % 3 == 0)
				[file writeString: @",\n\t"];
			else
				[file writeString: @", "];
		}
	}

	[file writeString: @"\n};\n\n"];

	/* Write of_unicode_decomposition_table */
	/* Write OFUnicodeDecompositionTable */
	[file writeFormat: @"const char *const "
			   @"*of_unicode_decomposition_table[0x%X] = {\n\t",
			   @"*OFUnicodeDecompositionTable[0x%X] = {\n\t",
			   _decompositionTableSize];

	for (OFUnichar i = 0; i < _decompositionTableSize; i++) {
		if (_decompositionTableUsed[i])
			[file writeFormat: @"decompositionPage%u", i];
		else
			[file writeString: @"emptyDecompositionPage"];

		if (i + 1 < _decompositionTableSize) {
			if ((i + 1) % 3 == 0)
				[file writeString: @",\n\t"];
			else
				[file writeString: @", "];
		}
	}

	[file writeString: @"\n};\n\n"];

	/* Write of_unicode_decomposition_compat_table */
	/* Write OFUnicodeDecompositionCompatTable */
	[file writeFormat: @"const char *const "
			   @"*of_unicode_decomposition_compat_table[0x%X] = {"
			   @"*OFUnicodeDecompositionCompatTable[0x%X] = {"
			   @"\n\t",
			   _decompositionCompatTableSize];

	for (OFUnichar i = 0; i < _decompositionCompatTableSize; i++) {
		if (_decompositionCompatTableUsed[i] == 1)
			[file writeFormat: @"decompCompatPage%u", i];
		else if (_decompositionCompatTableUsed[i] == 2)
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
759
760

761
762
763
764


765
766

767

768
769
770
771
772
773
774
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


759
760
761

762

763
764
765
766
767
768
769
770







-
-
-
-
-
-
+
+
+
+
+
+

-
+







-
+
-

-
+
-

-
+
-

-
+
-

-
-
+
+

-
+
-
+







	OFFile *file = [OFFile fileWithPath: path
				       mode: @"w"];

	[file writeString: COPYRIGHT
	    @"#import \"OFString.h\"\n\n"];

	[file writeFormat:
	    @"#define OF_UNICODE_UPPERCASE_TABLE_SIZE 0x%X\n"
	    @"#define OF_UNICODE_LOWERCASE_TABLE_SIZE 0x%X\n"
	    @"#define OF_UNICODE_TITLECASE_TABLE_SIZE 0x%X\n"
	    @"#define OF_UNICODE_CASEFOLDING_TABLE_SIZE 0x%X\n"
	    @"#define OF_UNICODE_DECOMPOSITION_TABLE_SIZE 0x%X\n"
	    @"#define OF_UNICODE_DECOMPOSITION_COMPAT_TABLE_SIZE 0x%X\n\n",
	    @"#define OFUnicodeUppercaseTableSize 0x%X\n"
	    @"#define OFUnicodeLowercaseTableSize 0x%X\n"
	    @"#define OFUnicodeTitlecaseTableSize 0x%X\n"
	    @"#define OFUnicodeCaseFoldingTableSize 0x%X\n"
	    @"#define OFUnicodeDecompositionTableSize 0x%X\n"
	    @"#define OFUnicodeDecompositionCompatTableSize 0x%X\n\n",
	    _uppercaseTableSize, _lowercaseTableSize, _titlecaseTableSize,
	    _casefoldingTableSize, _decompositionTableSize,
	    _caseFoldingTableSize, _decompositionTableSize,
	    _decompositionCompatTableSize];

	[file writeString:
	    @"#ifdef __cplusplus\n"
	    @"extern \"C\" {\n"
	    @"#endif\n"
	    @"extern const OFUnichar *const _Nonnull\n"
	    @"    of_unicode_uppercase_table["
	    @"    OFUnicodeUppercaseTable[OFUnicodeUppercaseTableSize];\n"
	    @"OF_UNICODE_UPPERCASE_TABLE_SIZE];\n"
	    @"extern const OFUnichar *const _Nonnull\n"
	    @"    of_unicode_lowercase_table["
	    @"    OFUnicodeLowercaseTable[OFUnicodeLowercaseTableSize];\n"
	    @"OF_UNICODE_LOWERCASE_TABLE_SIZE];\n"
	    @"extern const OFUnichar *const _Nonnull\n"
	    @"    of_unicode_titlecase_table["
	    @"    OFUnicodeTitlecaseTable[OFUnicodeTitlecaseTableSize];\n"
	    @"OF_UNICODE_TITLECASE_TABLE_SIZE];\n"
	    @"extern const OFUnichar *const _Nonnull\n"
	    @"    of_unicode_casefolding_table["
	    @"    OFUnicodeCaseFoldingTable[OFUnicodeCaseFoldingTableSize];\n"
	    @"OF_UNICODE_CASEFOLDING_TABLE_SIZE];\n"
	    @"extern const char *const _Nullable *const _Nonnull\n"
	    @"    of_unicode_decomposition_table["
	    @"OF_UNICODE_DECOMPOSITION_TABLE_SIZE];\n"
	    @"    OFUnicodeDecompositionTable["
	    @"OFUnicodeDecompositionTableSize];\n"
	    @"extern const char *const _Nullable *const _Nonnull\n"
	    @"    of_unicode_decomposition_compat_table["
	    @"    OFUnicodeDecompositionCompatTable["
	    @"OF_UNICODE_DECOMPOSITION_COMPAT_TABLE_SIZE];\n"
	    @"OFUnicodeDecompositionCompatTableSize];\n"
	    @"#ifdef __cplusplus\n"
	    @"}\n"
	    @"#endif\n"];

	objc_autoreleasePoolPop(pool);
}
@end

Modified src/OFASPrintF.m from [44b0400cd9] to [700e7dd91c].

414
415
416
417
418
419
420
421

422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450
451
452

453
454
455
456
457
458
459
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440

441
442
443
444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459







-
+



















-
+










-
+







		if (ctx->lengthModifier != LengthModifierNone)
			return false;

		ctx->subformat[ctx->subformatLen - 1] = 's';

		{
			char buffer[5];
			size_t len = of_string_utf8_encode(
			size_t len = OFUTF8StringEncode(
			    va_arg(ctx->arguments, OFUnichar), buffer);

			if (len == 0)
				return false;

			buffer[len] = 0;
			tmpLen = asprintf(&tmp, ctx->subformat, buffer);
		}

		break;
	case 'S':
		if (ctx->lengthModifier != LengthModifierNone)
			return false;

		ctx->subformat[ctx->subformatLen - 1] = 's';

		{
			const OFUnichar *arg =
			    va_arg(ctx->arguments, const OFUnichar *);
			size_t j, len = of_string_utf32_length(arg);
			size_t j, len = OFUTF32StringLength(arg);
			char *buffer;

			if (SIZE_MAX / 4 < len || (SIZE_MAX / 4) - len < 1)
				return false;

			if ((buffer = malloc((len * 4) + 1)) == NULL)
				return false;

			j = 0;
			for (size_t i = 0; i < len; i++) {
				size_t clen = of_string_utf8_encode(arg[i],
				size_t clen = OFUTF8StringEncode(arg[i],
				    buffer + j);

				if (clen == 0) {
					free(buffer);
					return false;
				}

Modified src/OFApplication.h from [2ca542568c] to [5f5127d646].

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






61
62
63
64
65
66
67
48
49
50
51
52
53
54






55
56
57
58
59
60
61
62
63
64
65
66
67







-
-
-
-
-
-
+
+
+
+
+
+







 * - (void)applicationDidFinishLaunching
 * {
 *         [OFApplication terminate];
 * }
 * @end
 * @endcode
 */
#define OF_APPLICATION_DELEGATE(class_)					\
	int								\
	main(int argc, char *argv[])					\
	{								\
		return of_application_main(&argc, &argv,		\
		    (class_ *)[[class_ alloc] init]);			\
#define OF_APPLICATION_DELEGATE(class_)			\
	int						\
	main(int argc, char *argv[])			\
	{						\
		return OFApplicationMain(&argc, &argv,	\
		    (class_ *)[[class_ alloc] init]);	\
	}

#ifdef OF_HAVE_PLEDGE
# define OF_HAVE_SANDBOX
#endif

/**
278
279
280
281
282
283
284
285
286


287
288
289
290
291
278
279
280
281
282
283
284


285
286
287
288
289
290
291







-
-
+
+





- (void)of_activateSandboxForChildProcesses: (OFSandbox *)sandbox;
#endif
@end

#ifdef __cplusplus
extern "C" {
#endif
extern int of_application_main(int *_Nonnull,
    char *_Nullable *_Nonnull[_Nonnull], id <OFApplicationDelegate>);
extern int OFApplicationMain(int *_Nonnull, char *_Nullable *_Nonnull[_Nonnull],
    id <OFApplicationDelegate>);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFApplication.m from [89530fe0bb] to [9af79ccbcf].

90
91
92
93
94
95
96
97

98
99
100
101
102
103

104
105
106
107
108
109
110
90
91
92
93
94
95
96

97
98
99
100
101


102
103
104
105
106
107
108
109







-
+




-
-
+







	if ([delegate respondsToSelector: @selector(applicationWillTerminate)])
		[delegate applicationWillTerminate];

	[delegate release];

#if defined(OF_HAVE_THREADS) && defined(OF_HAVE_SOCKETS) && \
    defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
	of_socket_deinit();
	OFSocketDeinit();
#endif
}

int
of_application_main(int *argc, char **argv[],
    id <OFApplicationDelegate> delegate)
OFApplicationMain(int *argc, char **argv[], id <OFApplicationDelegate> delegate)
{
#ifdef OF_WINDOWS
	wchar_t **wargv, **wenvp;
	int wargc, si = 0;
#endif

	[[OFLocale alloc] init];
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240







-
+







			env = env0 = GetEnvironmentStringsW();

			while (*env != 0) {
				void *pool = objc_autoreleasePoolPush();
				OFString *tmp, *key, *value;
				size_t length, pos;

				length = of_string_utf16_length(env);
				length = OFUTF16StringLength(env);
				tmp = [OFString stringWithUTF16String: env
							       length: length];
				env += length + 1;

				/*
				 * cmd.exe seems to add some special variables
				 * which start with a "=", even though variable

Modified src/OFBytesValue.m from [1aadb38986] to [cd6955a0ec].

23
24
25
26
27
28
29
30

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

30
31
32
33
34
35
36
37







-
+








- (instancetype)initWithBytes: (const void *)bytes
		     objCType: (const char *)objCType
{
	self = [super init];

	@try {
		_size = of_sizeof_type_encoding(objCType);
		_size = OFSizeOfTypeEncoding(objCType);
		_objCType = objCType;
		_bytes = OFAllocMemory(1, _size);

		memcpy(_bytes, bytes, _size);
	} @catch (id e) {
		[self release];
		@throw e;

Modified src/OFConstantString.m from [df00a8f5dc] to [a046d60efd].

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
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







-
+








-
-
+
+







	objc_registerClassPair((Class)&_OFConstantStringClassReference);
#endif
}

- (void)finishInitialization
{
	@synchronized (self) {
		struct of_string_utf8_ivars *ivars;
		struct OFUTF8StringIvars *ivars;

		if ([self isMemberOfClass: [OFConstantUTF8String class]])
			return;

		ivars = OFAllocZeroedMemory(1, sizeof(*ivars));
		ivars->cString = _cString;
		ivars->cStringLength = _cStringLength;

		switch (of_string_utf8_check(ivars->cString,
		    ivars->cStringLength, &ivars->length)) {
		switch (OFUTF8StringCheck(ivars->cString, ivars->cStringLength,
		    &ivars->length)) {
		case 1:
			ivars->isUTF8 = true;
			break;
		case -1:
			OFFreeMemory(ivars);
			@throw [OFInvalidEncodingException exception];
		}

Modified src/OFDNSResolver.m from [52dce07be7] to [2c62153187].

556
557
558
559
560
561
562
563

564
565
566
567
568
569
570
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570







-
+







@implementation OFDNSResolver
#ifdef OF_AMIGAOS
+ (void)initialize
{
	if (self != [OFDNSResolver class])
		return;

	if (!of_socket_init())
	if (!OFSocketInit())
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}
#endif

+ (instancetype)resolver
{

Modified src/OFDatagramSocket.m from [b69241363b] to [b34095fe0b].

46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60







-
+







@synthesize delegate = _delegate;

+ (void)initialize
{
	if (self != [OFDatagramSocket class])
		return;

	if (!of_socket_init())
	if (!OFSocketInit())
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}

+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
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
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







-
+















-
+
















-
+







	_canBlock = canBlock;
#elif defined(OF_WINDOWS)
	u_long v = canBlock;

	if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR)
		@throw [OFSetOptionFailedException
		    exceptionWithObject: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

	_canBlock = canBlock;
#else
	OF_UNRECOGNIZED_SELECTOR
#endif
}

- (void)setCanSendToBroadcastAddresses: (bool)canSendToBroadcastAddresses
{
	int v = canSendToBroadcastAddresses;

	if (setsockopt(_socket, SOL_SOCKET, SO_BROADCAST,
	    (char *)&v, (socklen_t)sizeof(v)) != 0)
		@throw [OFSetOptionFailedException
		    exceptionWithObject: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

#ifdef OF_WII
	_canSendToBroadcastAddresses = canSendToBroadcastAddresses;
#endif
}

- (bool)canSendToBroadcastAddresses
{
#ifndef OF_WII
	int v;
	socklen_t len = sizeof(v);

	if (getsockopt(_socket, SOL_SOCKET, SO_BROADCAST,
	    (char *)&v, &len) != 0 || len != sizeof(v))
		@throw [OFGetOptionFailedException
		    exceptionWithObject: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

	return v;
#else
	return _canSendToBroadcastAddresses;
#endif
}

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
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







-
+









-
+








#ifndef OF_WINDOWS
	if ((ret = recvfrom(_socket, buffer, length, 0,
	    &sender->sockaddr.sockaddr, &sender->length)) < 0)
		@throw [OFReadFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#else
	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if ((ret = recvfrom(_socket, buffer, (int)length, 0,
	    &sender->sockaddr.sockaddr, &sender->length)) < 0)
		@throw [OFReadFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#endif

	switch (sender->sockaddr.sockaddr.sa_family) {
	case AF_INET:
		sender->family = OFSocketAddressFamilyIPv4;
		break;
#ifdef OF_HAVE_IPV6
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
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







-
+












-
+







	if ((bytesWritten = sendto(_socket, (void *)buffer, length, 0,
	    (struct sockaddr *)&receiver->sockaddr.sockaddr,
	    receiver->length)) < 0)
		@throw [OFWriteFailedException
		    exceptionWithObject: self
			requestedLength: length
			   bytesWritten: 0
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#else
	int bytesWritten;

	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if ((bytesWritten = sendto(_socket, buffer, (int)length, 0,
	    &receiver->sockaddr.sockaddr, receiver->length)) < 0)
		@throw [OFWriteFailedException
		    exceptionWithObject: self
			requestedLength: length
			   bytesWritten: 0
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#endif

	if ((size_t)bytesWritten != length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length
						      bytesWritten: bytesWritten
							     errNo: 0];

Modified src/OFHTTPClient.m from [1919d7db7a] to [5869517d16].

695
696
697
698
699
700
701
702

703
704
705
706

707
708
709
710
711
712
713
695
696
697
698
699
700
701

702
703
704
705

706
707
708
709
710
711
712
713







-
+



-
+







		uint16_t port;
		OFNumber *URLPort;

		[_client close];

		if ([URL.scheme caseInsensitiveCompare: @"https"] ==
		    OFOrderedSame) {
			if (of_tls_socket_class == Nil)
			if (OFTLSSocketClass == Nil)
				@throw [OFUnsupportedProtocolException
				    exceptionWithURL: URL];

			sock = [[[of_tls_socket_class alloc] init] autorelease];
			sock = [[[OFTLSSocketClass alloc] init] autorelease];
			port = 443;
		} else {
			sock = [OFTCPSocket socket];
			port = 80;
		}

		URLPort = URL.port;

Modified src/OFHTTPServer.m from [d0e0c65c22] to [77e13e0b81].

901
902
903
904
905
906
907
908

909
910
911

912
913
914
915
916
917
918
901
902
903
904
905
906
907

908
909
910

911
912
913
914
915
916
917
918







-
+


-
+








	if (_listeningSocket != nil)
		@throw [OFAlreadyConnectedException exception];

	if (_usesTLS) {
		OFTCPSocket <OFTLSSocket> *TLSSocket;

		if (of_tls_socket_class == Nil)
		if (OFTLSSocketClass == Nil)
			@throw [OFUnsupportedProtocolException exception];

		TLSSocket = [[of_tls_socket_class alloc] init];
		TLSSocket = [[OFTLSSocketClass alloc] init];
		_listeningSocket = TLSSocket;

		TLSSocket.certificateFile = _certificateFile;
		TLSSocket.privateKeyFile = _privateKeyFile;
		TLSSocket.privateKeyPassphrase = _privateKeyPassphrase;
	} else
		_listeningSocket = [[OFTCPSocket alloc] init];

Modified src/OFIPXSocket.m from [65bb8549ab] to [7ffe9acbc2].

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
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







-
+









-
+














-
+

-
+








	if ((_socket = socket(address.sockaddr.sockaddr.sa_family,
	    SOCK_DGRAM | SOCK_CLOEXEC, protocol)) == INVALID_SOCKET)
		@throw [OFBindFailedException
		    exceptionWithPort: port
			   packetType: packetType
			       socket: self
				errNo: of_socket_errno()];
				errNo: OFSocketErrNo()];

	_canBlock = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC)
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

	if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) {
		int errNo = of_socket_errno();
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithPort: port
						     packetType: packetType
							 socket: self
							  errNo: errNo];
	}

	memset(&address, 0, sizeof(address));
	address.family = OFSocketAddressFamilyIPX;
	address.length = (socklen_t)sizeof(address.sockaddr);

	if (of_getsockname(_socket, &address.sockaddr.sockaddr,
	if (OFGetSockName(_socket, &address.sockaddr.sockaddr,
	    &address.length) != 0) {
		int errNo = of_socket_errno();
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithPort: port
						     packetType: packetType
							 socket: self

Modified src/OFInvocation.m from [ea63101931] to [a2a3075eb5].

44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67







-
+








-
+







		_arguments = [[OFMutableArray alloc] init];

		for (size_t i = 0; i < numberOfArguments; i++) {
			OFMutableData *data;

			typeEncoding = [_methodSignature
			    argumentTypeAtIndex: i];
			typeSize = of_sizeof_type_encoding(typeEncoding);
			typeSize = OFSizeOfTypeEncoding(typeEncoding);

			data = [OFMutableData dataWithItemSize: typeSize
						      capacity: 1];
			[data increaseCountBy: 1];
			[_arguments addObject: data];
		}

		typeEncoding = _methodSignature.methodReturnType;
		typeSize = of_sizeof_type_encoding(typeEncoding);
		typeSize = OFSizeOfTypeEncoding(typeEncoding);

		if (typeSize > 0) {
			_returnValue = [[OFMutableData alloc]
			    initWithItemSize: typeSize
				    capacity: 1];
			[_returnValue increaseCountBy: 1];
		}

Modified src/OFKernelEventObserver.m from [66fc5201d9] to [1b43b5b3cb].

66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80







-
+







#endif

+ (void)initialize
{
	if (self != [OFKernelEventObserver class])
		return;

	if (!of_socket_init())
	if (!OFSocketInit())
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}

+ (instancetype)observer
{
	return [[[self alloc] init] autorelease];
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
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







-
+



















-
+







# if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
		if (bind(_cancelFD[0], (struct sockaddr *)&_cancelAddr,
		    sizeof(_cancelAddr)) != 0)
			@throw [OFInitializationFailedException
			    exceptionWithClass: self.class];

		cancelAddrLen = sizeof(_cancelAddr);
		if (of_getsockname(_cancelFD[0],
		if (OFGetSockName(_cancelFD[0],
		    (struct sockaddr *)&_cancelAddr, &cancelAddrLen) != 0)
			@throw [OFInitializationFailedException
			    exceptionWithClass: self.class];
# else
		for (;;) {
			uint16_t rnd = 0;
			int ret;

			while (rnd < 1024)
				rnd = (uint16_t)rand();

			_cancelAddr.sin_port = OFToBigEndian16(rnd);
			ret = bind(_cancelFD[0],
			    (struct sockaddr *)&_cancelAddr,
			    sizeof(_cancelAddr));

			if (ret == 0)
				break;

			if (of_socket_errno() != EADDRINUSE)
			if (OFSocketErrNo() != EADDRINUSE)
				@throw [OFInitializationFailedException
				    exceptionWithClass: self.class];
		}
# endif
#endif
	} @catch (id e) {
		[self release];

Modified src/OFMethodSignature.h from [02180a8d88] to [11b966e495].

90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105

106
107
108
109
110
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104

105
106
107
108
109
110







-
+







-
+





#endif
/**
 * @brief Returns the size for the specified type encoding.
 *
 * @param type The type encoding to return the size for
 * @return The size for the specified type encoding
 */
extern size_t of_sizeof_type_encoding(const char *type);
extern size_t OFSizeOfTypeEncoding(const char *type);

/**
 * @brief Returns the alignment for the specified type encoding.
 *
 * @param type The type encoding to return the alignment for
 * @return The alignment for the specified type encoding
 */
extern size_t of_alignof_type_encoding(const char *type);
extern size_t OFAlignmentOfTypeEncoding(const char *type);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFMethodSignature.m from [53da315529] to [674f1f49e8].

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
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







-
-
+
+
+
















-
+








#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"

#import "macros.h"

static size_t alignofEncoding(const char **type, size_t *length, bool inStruct);
static size_t sizeofEncoding(const char **type, size_t *length);
static size_t alignmentOfEncoding(const char **type, size_t *length,
    bool inStruct);
static size_t sizeOfEncoding(const char **type, size_t *length);

static size_t
alignofArray(const char **type, size_t *length)
{
	size_t align;

	assert(*length > 0);

	(*type)++;
	(*length)--;

	while (*length > 0 && OFASCIIIsDigit(**type)) {
		(*type)++;
		(*length)--;
	}

	align = alignofEncoding(type, length, true);
	align = alignmentOfEncoding(type, length, true);

	if (*length == 0 || **type != ']')
		@throw [OFInvalidFormatException exception];

	(*type)++;
	(*length)--;

79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94







-
+







		@throw [OFInvalidFormatException exception];

	/* Skip '=' */
	(*type)++;
	(*length)--;

	while (*length > 0 && **type != '}') {
		size_t fieldAlign = alignofEncoding(type, length, true);
		size_t fieldAlign = alignmentOfEncoding(type, length, true);

#if defined(OF_POWERPC) && defined(OF_MACOS)
		if (!first && fieldAlign > 4)
			fieldAlign = 4;

		first = false;
#endif
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
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







-
+















-
+







		@throw [OFInvalidFormatException exception];

	/* Skip '=' */
	(*type)++;
	(*length)--;

	while (*length > 0 && **type != ')') {
		size_t fieldAlign = alignofEncoding(type, length, true);
		size_t fieldAlign = alignmentOfEncoding(type, length, true);

		if (fieldAlign > align)
			align = fieldAlign;
	}

	if (*length == 0 || **type != ')')
		@throw [OFInvalidFormatException exception];

	(*type)++;
	(*length)--;

	return align;
}

static size_t
alignofEncoding(const char **type, size_t *length, bool inStruct)
alignmentOfEncoding(const char **type, size_t *length, bool inStruct)
{
	size_t align;

	if (*length == 0)
		@throw [OFInvalidFormatException exception];

	if (**type == 'r') {
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250







-
+







		return alignofStruct(type, length);
	case '(':
		return alignofUnion(type, length);
	case '^':
		/* Just to skip over the rest */
		(*type)++;
		(*length)--;
		alignofEncoding(type, length, false);
		alignmentOfEncoding(type, length, false);

		return OF_ALIGNOF(void *);
#ifndef __STDC_NO_COMPLEX__
	case 'j':
		(*type)++;
		(*length)--;

298
299
300
301
302
303
304
305

306
307
308
309
310
311
312
299
300
301
302
303
304
305

306
307
308
309
310
311
312
313







-
+







		(*type)++;
		(*length)--;
	}

	if (count == 0)
		@throw [OFInvalidFormatException exception];

	size = sizeofEncoding(type, length);
	size = sizeOfEncoding(type, length);

	if (*length == 0 || **type != ']')
		@throw [OFInvalidFormatException exception];

	(*type)++;
	(*length)--;

346
347
348
349
350
351
352
353
354


355
356
357
358
359
360
361
347
348
349
350
351
352
353


354
355
356
357
358
359
360
361
362







-
-
+
+







	(*length)--;

	while (*length > 0 && **type != '}') {
		size_t fieldSize, fieldAlign;

		typeCopy = *type;
		lengthCopy = *length;
		fieldSize = sizeofEncoding(type, length);
		fieldAlign = alignofEncoding(&typeCopy, &lengthCopy, true);
		fieldSize = sizeOfEncoding(type, length);
		fieldAlign = alignmentOfEncoding(&typeCopy, &lengthCopy, true);

#if defined(OF_POWERPC) && defined(OF_MACOS)
		if (!first && fieldAlign > 4)
			fieldAlign = 4;

		first = false;
#endif
413
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444







-
+















-
+







		@throw [OFInvalidFormatException exception];

	/* Skip '=' */
	(*type)++;
	(*length)--;

	while (*length > 0 && **type != ')') {
		size_t fieldSize = sizeofEncoding(type, length);
		size_t fieldSize = sizeOfEncoding(type, length);

		if (fieldSize > size)
			size = fieldSize;
	}

	if (*length == 0 || **type != ')')
		@throw [OFInvalidFormatException exception];

	(*type)++;
	(*length)--;

	return size;
}

static size_t
sizeofEncoding(const char **type, size_t *length)
sizeOfEncoding(const char **type, size_t *length)
{
	size_t size;

	if (*length == 0)
		@throw [OFInvalidFormatException exception];

	if (**type == 'r') {
508
509
510
511
512
513
514
515

516
517
518
519
520
521
522
509
510
511
512
513
514
515

516
517
518
519
520
521
522
523







-
+







		return sizeofStruct(type, length);
	case '(':
		return sizeofUnion(type, length);
	case '^':
		/* Just to skip over the rest */
		(*type)++;
		(*length)--;
		sizeofEncoding(type, length);
		sizeOfEncoding(type, length);

		return sizeof(void *);
#ifndef __STDC_NO_COMPLEX__
	case 'j':
		(*type)++;
		(*length)--;

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
572
573
574
575
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
572
573
574
575
576







-
+


-
+








-
+


-
+







	(*type)++;
	(*length)--;

	return size;
}

size_t
of_sizeof_type_encoding(const char *type)
OFSizeOfTypeEncoding(const char *type)
{
	size_t length = strlen(type);
	size_t ret = sizeofEncoding(&type, &length);
	size_t ret = sizeOfEncoding(&type, &length);

	if (length > 0)
		@throw [OFInvalidFormatException exception];

	return ret;
}

size_t
of_alignof_type_encoding(const char *type)
OFAlignmentOfTypeEncoding(const char *type)
{
	size_t length = strlen(type);
	size_t ret = alignofEncoding(&type, &length, false);
	size_t ret = alignmentOfEncoding(&type, &length, false);

	if (length > 0)
		@throw [OFInvalidFormatException exception];

	return ret;
}

Modified src/OFMutableString.m from [75824153ee] to [7608f6e984].

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
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







-
-
-
-
+
+
+
+




-
-
-
-
+
+
+
+




-
-
-
-
+
+
+
+







		[self setCharacter: tmp atIndex: i];
	}
}

#ifdef OF_HAVE_UNICODE_TABLES
- (void)uppercase
{
	[self of_convertWithWordStartTable: of_unicode_uppercase_table
			   wordMiddleTable: of_unicode_uppercase_table
			wordStartTableSize: OF_UNICODE_UPPERCASE_TABLE_SIZE
		       wordMiddleTableSize: OF_UNICODE_UPPERCASE_TABLE_SIZE];
	[self of_convertWithWordStartTable: OFUnicodeUppercaseTable
			   wordMiddleTable: OFUnicodeUppercaseTable
			wordStartTableSize: OFUnicodeUppercaseTableSize
		       wordMiddleTableSize: OFUnicodeUppercaseTableSize];
}

- (void)lowercase
{
	[self of_convertWithWordStartTable: of_unicode_lowercase_table
			   wordMiddleTable: of_unicode_lowercase_table
			wordStartTableSize: OF_UNICODE_LOWERCASE_TABLE_SIZE
		       wordMiddleTableSize: OF_UNICODE_LOWERCASE_TABLE_SIZE];
	[self of_convertWithWordStartTable: OFUnicodeLowercaseTable
			   wordMiddleTable: OFUnicodeLowercaseTable
			wordStartTableSize: OFUnicodeLowercaseTableSize
		       wordMiddleTableSize: OFUnicodeLowercaseTableSize];
}

- (void)capitalize
{
	[self of_convertWithWordStartTable: of_unicode_titlecase_table
			   wordMiddleTable: of_unicode_lowercase_table
			wordStartTableSize: OF_UNICODE_TITLECASE_TABLE_SIZE
		       wordMiddleTableSize: OF_UNICODE_LOWERCASE_TABLE_SIZE];
	[self of_convertWithWordStartTable: OFUnicodeTitlecaseTable
			   wordMiddleTable: OFUnicodeLowercaseTable
			wordStartTableSize: OFUnicodeTitlecaseTableSize
		       wordMiddleTableSize: OFUnicodeLowercaseTableSize];
}
#else
- (void)uppercase
{
	convert(self, OFASCIIToUpper, OFASCIIToUpper);
}

Modified src/OFMutableURL.m from [baeb186c19] to [f132d62e1d].

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


29
30
31
32
33
34
35







-
-







# import "OFFileManager.h"
#endif
#import "OFNumber.h"
#import "OFString.h"

#import "OFInvalidFormatException.h"

extern void of_url_verify_escaped(OFString *, OFCharacterSet *);

@implementation OFMutableURL
@dynamic scheme, URLEncodedScheme, host, URLEncodedHost, port, user;
@dynamic URLEncodedUser, password, URLEncodedPassword, path, URLEncodedPath;
@dynamic pathComponents, query, URLEncodedQuery, queryDictionary, fragment;
@dynamic URLEncodedFragment;

+ (instancetype)URL
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
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







-
+












-
+


















-
+



-
+







}

- (void)setURLEncodedScheme: (OFString *)URLEncodedScheme
{
	OFString *old;

	if (URLEncodedScheme != nil)
		of_url_verify_escaped(URLEncodedScheme,
		OFURLVerifyEscaped(URLEncodedScheme,
		    [OFCharacterSet URLSchemeAllowedCharacterSet]);

	old = _URLEncodedScheme;
	_URLEncodedScheme = [URLEncodedScheme copy];
	[old release];
}

- (void)setHost: (OFString *)host
{
	void *pool = objc_autoreleasePoolPush();
	OFString *old = _URLEncodedHost;

	if (of_url_is_ipv6_host(host))
	if (OFURLIsIPv6Host(host))
		_URLEncodedHost = [[OFString alloc]
		    initWithFormat: @"[%@]", host];
	else
		_URLEncodedHost = [[host
		    stringByURLEncodingWithAllowedCharacters:
		    [OFCharacterSet URLHostAllowedCharacterSet]] copy];

	[old release];

	objc_autoreleasePoolPop(pool);
}

- (void)setURLEncodedHost: (OFString *)URLEncodedHost
{
	OFString *old;

	if ([URLEncodedHost hasPrefix: @"["] &&
	    [URLEncodedHost hasSuffix: @"]"]) {
		if (!of_url_is_ipv6_host([URLEncodedHost substringWithRange:
		if (!OFURLIsIPv6Host([URLEncodedHost substringWithRange:
		    OFRangeMake(1, URLEncodedHost.length - 2)]))
			@throw [OFInvalidFormatException exception];
	} else if (URLEncodedHost != nil)
		of_url_verify_escaped(URLEncodedHost,
		OFURLVerifyEscaped(URLEncodedHost,
		    [OFCharacterSet URLHostAllowedCharacterSet]);

	old = _URLEncodedHost;
	_URLEncodedHost = [URLEncodedHost copy];
	[old release];
}

122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
+







}

- (void)setURLEncodedUser: (OFString *)URLEncodedUser
{
	OFString *old;

	if (URLEncodedUser != nil)
		of_url_verify_escaped(URLEncodedUser,
		OFURLVerifyEscaped(URLEncodedUser,
		    [OFCharacterSet URLUserAllowedCharacterSet]);

	old = _URLEncodedUser;
	_URLEncodedUser = [URLEncodedUser copy];
	[old release];
}

149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161







-
+







}

- (void)setURLEncodedPassword: (OFString *)URLEncodedPassword
{
	OFString *old;

	if (URLEncodedPassword != nil)
		of_url_verify_escaped(URLEncodedPassword,
		OFURLVerifyEscaped(URLEncodedPassword,
		    [OFCharacterSet URLPasswordAllowedCharacterSet]);

	old = _URLEncodedPassword;
	_URLEncodedPassword = [URLEncodedPassword copy];
	[old release];
}

175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187







-
+







}

- (void)setURLEncodedPath: (OFString *)URLEncodedPath
{
	OFString *old;

	if (URLEncodedPath != nil)
		of_url_verify_escaped(URLEncodedPath,
		OFURLVerifyEscaped(URLEncodedPath,
		    [OFCharacterSet URLPathAllowedCharacterSet]);

	old = _URLEncodedPath;
	_URLEncodedPath = [URLEncodedPath copy];
	[old release];
}

221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233







-
+







}

- (void)setURLEncodedQuery: (OFString *)URLEncodedQuery
{
	OFString *old;

	if (URLEncodedQuery != nil)
		of_url_verify_escaped(URLEncodedQuery,
		OFURLVerifyEscaped(URLEncodedQuery,
		    [OFCharacterSet URLQueryAllowedCharacterSet]);

	old = _URLEncodedQuery;
	_URLEncodedQuery = [URLEncodedQuery copy];
	[old release];
}

289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301







-
+







}

- (void)setURLEncodedFragment: (OFString *)URLEncodedFragment
{
	OFString *old;

	if (URLEncodedFragment != nil)
		of_url_verify_escaped(URLEncodedFragment,
		OFURLVerifyEscaped(URLEncodedFragment,
		    [OFCharacterSet URLFragmentAllowedCharacterSet]);

	old = _URLEncodedFragment;
	_URLEncodedFragment = [URLEncodedFragment copy];
	[old release];
}

Modified src/OFMutableUTF8String.h from [15b5339be2] to [ef5fa816c6].

16
17
18
19
20
21
22
23
24


25
26
27
28
16
17
18
19
20
21
22


23
24
25
26
27
28







-
-
+
+




#import "OFMutableString.h"
#import "OFUTF8String.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFMutableUTF8String: OFMutableString
{
	struct of_string_utf8_ivars *restrict _s;
	struct of_string_utf8_ivars _storage;
	struct OFUTF8StringIvars *restrict _s;
	struct OFUTF8StringIvars _storage;
}
@end

OF_ASSUME_NONNULL_END

Modified src/OFMutableUTF8String.m from [06bda2db53] to [0d95785aef].

114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128







-
+







			table = startTable;
			tableSize = middleTableSize;
		} else {
			table = middleTable;
			tableSize = middleTableSize;
		}

		cLen = of_string_utf8_decode(_s->cString + i,
		cLen = OFUTF8StringDecode(_s->cString + i,
		    _s->cStringLength - i, &c);

		if (cLen <= 0 || c > 0x10FFFF) {
			OFFreeMemory(unicodeString);
			@throw [OFInvalidEncodingException exception];
		}

160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174







-
+







	}

	j = 0;

	for (i = 0; i < unicodeLen; i++) {
		size_t d;

		if ((d = of_string_utf8_encode(unicodeString[i],
		if ((d = OFUTF8StringEncode(unicodeString[i],
		    newCString + j)) == 0) {
			OFFreeMemory(unicodeString);
			OFFreeMemory(newCString);
			@throw [OFInvalidEncodingException exception];
		}
		j += d;
	}
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
222
223
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
222
223







-
+












-
+


-
+







{
	char buffer[4];
	OFUnichar c;
	size_t lenNew;
	ssize_t lenOld;

	if (_s->isUTF8)
		idx = of_string_utf8_get_position(_s->cString, idx,
		idx = OFUTF8StringIndexToPosition(_s->cString, idx,
		    _s->cStringLength);

	if (idx >= _s->cStringLength)
		@throw [OFOutOfRangeException exception];

	/* Shortcut if old and new character both are ASCII */
	if (character < 0x80 && !(_s->cString[idx] & 0x80)) {
		_s->hashed = false;
		_s->cString[idx] = character;
		return;
	}

	if ((lenNew = of_string_utf8_encode(character, buffer)) == 0)
	if ((lenNew = OFUTF8StringEncode(character, buffer)) == 0)
		@throw [OFInvalidEncodingException exception];

	if ((lenOld = of_string_utf8_decode(_s->cString + idx,
	if ((lenOld = OFUTF8StringDecode(_s->cString + idx,
	    _s->cStringLength - idx, &c)) <= 0)
		@throw [OFInvalidEncodingException exception];

	_s->hashed = false;

	if (lenNew == (size_t)lenOld)
		memcpy(_s->cString + idx, buffer, lenNew);
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277







-
+








	if (UTF8StringLength >= 3 &&
	    memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) {
		UTF8String += 3;
		UTF8StringLength -= 3;
	}

	switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) {
	switch (OFUTF8StringCheck(UTF8String, UTF8StringLength, &length)) {
	case 1:
		_s->isUTF8 = true;
		break;
	case -1:
		@throw [OFInvalidEncodingException exception];
	}

292
293
294
295
296
297
298
299

300
301
302
303
304
305
306
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306







-
+








	if (UTF8StringLength >= 3 &&
	    memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) {
		UTF8String += 3;
		UTF8StringLength -= 3;
	}

	switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) {
	switch (OFUTF8StringCheck(UTF8String, UTF8StringLength, &length)) {
	case 1:
		_s->isUTF8 = true;
		break;
	case -1:
		@throw [OFInvalidEncodingException exception];
	}

374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389
374
375
376
377
378
379
380

381

382
383
384
385
386
387
388







-
+
-







	char *tmp = OFAllocMemory((length * 4) + 1, 1);

	@try {
		size_t j = 0;
		bool isUTF8 = false;

		for (size_t i = 0; i < length; i++) {
			size_t len = of_string_utf8_encode(characters[i],
			size_t len = OFUTF8StringEncode(characters[i], tmp + j);
			    tmp + j);

			if (len == 0)
				@throw [OFInvalidEncodingException exception];

			if (len > 1)
				isUTF8 = true;

510
511
512
513
514
515
516
517

518
519
520
521
522
523
524
509
510
511
512
513
514
515

516
517
518
519
520
521
522
523







-
+







{
	size_t newCStringLength;

	if (idx > _s->length)
		@throw [OFOutOfRangeException exception];

	if (_s->isUTF8)
		idx = of_string_utf8_get_position(_s->cString, idx,
		idx = OFUTF8StringIndexToPosition(_s->cString, idx,
		    _s->cStringLength);

	newCStringLength = _s->cStringLength + string.UTF8StringLength;
	_s->hashed = false;
	_s->cString = OFResizeMemory(_s->cString, newCStringLength + 1, 1);

	memmove(_s->cString + idx + string.UTF8StringLength,
543
544
545
546
547
548
549
550

551
552

553
554
555
556
557
558
559
542
543
544
545
546
547
548

549
550

551
552
553
554
555
556
557
558







-
+

-
+







	size_t start = range.location;
	size_t end = range.location + range.length;

	if (range.length > SIZE_MAX - range.location || end > _s->length)
		@throw [OFOutOfRangeException exception];

	if (_s->isUTF8) {
		start = of_string_utf8_get_position(_s->cString, start,
		start = OFUTF8StringIndexToPosition(_s->cString, start,
		    _s->cStringLength);
		end = of_string_utf8_get_position(_s->cString, end,
		end = OFUTF8StringIndexToPosition(_s->cString, end,
		    _s->cStringLength);
	}

	memmove(_s->cString + start, _s->cString + end,
	    _s->cStringLength - end);
	_s->hashed = false;
	_s->length -= range.length;
580
581
582
583
584
585
586
587

588
589

590
591
592
593
594
595
596
579
580
581
582
583
584
585

586
587

588
589
590
591
592
593
594
595







-
+

-
+








	if (range.length > SIZE_MAX - range.location || end > _s->length)
		@throw [OFOutOfRangeException exception];

	newLength = _s->length - range.length + replacement.length;

	if (_s->isUTF8) {
		start = of_string_utf8_get_position(_s->cString, start,
		start = OFUTF8StringIndexToPosition(_s->cString, start,
		    _s->cStringLength);
		end = of_string_utf8_get_position(_s->cString, end,
		end = OFUTF8StringIndexToPosition(_s->cString, end,
		    _s->cStringLength);
	}

	newCStringLength = _s->cStringLength - (end - start) +
	    replacement.UTF8StringLength;
	_s->hashed = false;

647
648
649
650
651
652
653
654

655
656

657
658
659
660
661
662
663
646
647
648
649
650
651
652

653
654

655
656
657
658
659
660
661
662







-
+

-
+







		@throw [OFInvalidArgumentException exception];

	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > self.length)
		@throw [OFOutOfRangeException exception];

	if (_s->isUTF8) {
		range.location = of_string_utf8_get_position(_s->cString,
		range.location = OFUTF8StringIndexToPosition(_s->cString,
		    range.location, _s->cStringLength);
		range.length = of_string_utf8_get_position(
		range.length = OFUTF8StringIndexToPosition(
		    _s->cString + range.location, range.length,
		    _s->cStringLength - range.location);
	}

	if (string.UTF8StringLength > range.length)
		return;

Modified src/OFPlugin.h from [e247c60403] to [70b1b483a7].

50
51
52
53
54
55
56
57
58
59
60




61
62
63
64
65
50
51
52
53
54
55
56




57
58
59
60
61
62
63
64
65







-
-
-
-
+
+
+
+





 */
+ (OF_KINDOF(OFPlugin *))pluginWithPath: (OFString *)path;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern OFPluginHandle OFDlopen(OFString *path, int flags);
extern void *OFDlsym(OFPluginHandle handle, const char *symbol);
extern OFString *_Nullable OFDlerror(void);
extern void OFDlclose(OFPluginHandle handle);
extern OFPluginHandle OFDlOpen(OFString *path, int flags);
extern void *OFDlSym(OFPluginHandle handle, const char *symbol);
extern OFString *_Nullable OFDlError(void);
extern void OFDlClose(OFPluginHandle handle);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFPlugin.m from [b47ab783df] to [f022309a5c].

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
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







-
+
















-
+









-
+









-
+








#import "OFInitializationFailedException.h"
#import "OFLoadPluginFailedException.h"

typedef OFPlugin *(*init_plugin_t)(void);

OFPluginHandle
OFDlopen(OFString *path, int flags)
OFDlOpen(OFString *path, int flags)
{
#ifndef OF_WINDOWS
	return dlopen([path cStringWithEncoding: [OFLocale encoding]], flags);
#else
	if (path == nil)
		return GetModuleHandle(NULL);

	if ([OFSystemInfo isWindowsNT])
		return LoadLibraryW(path.UTF16String);
	else
		return LoadLibraryA(
		    [path cStringWithEncoding: [OFLocale encoding]]);
#endif
}

void *
OFDlsym(OFPluginHandle handle, const char *symbol)
OFDlSym(OFPluginHandle handle, const char *symbol)
{
#ifndef OF_WINDOWS
	return dlsym(handle, symbol);
#else
	return (void *)(uintptr_t)GetProcAddress(handle, symbol);
#endif
}

void
OFDlclose(OFPluginHandle handle)
OFDlClose(OFPluginHandle handle)
{
#ifndef OF_WINDOWS
	dlclose(handle);
#else
	FreeLibrary(handle);
#endif
}

OFString *
OFDlerror(void)
OFDlError(void)
{
#ifndef OF_WINDOWS
	return [OFString stringWithCString: dlerror()
				  encoding: [OFLocale encoding]];
#else
	return nil;
#endif
94
95
96
97
98
99
100
101

102
103
104

105
106
107
108

109
110

111
112
113
114
115
116
117
94
95
96
97
98
99
100

101
102
103

104
105
106
107

108
109

110
111
112
113
114
115
116
117







-
+


-
+



-
+

-
+







#elif defined(OF_IOS)
	path = [path stringByAppendingFormat: @".bundle/%@",
					      path.lastPathComponent];
#else
	path = [path stringByAppendingString: @PLUGIN_SUFFIX];
#endif

	if ((handle = OFDlopen(path, OF_RTLD_LAZY)) == NULL)
	if ((handle = OFDlOpen(path, OF_RTLD_LAZY)) == NULL)
		@throw [OFLoadPluginFailedException
		    exceptionWithPath: path
				error: OFDlerror()];
				error: OFDlError()];

	objc_autoreleasePoolPop(pool);

	initPlugin = (init_plugin_t)(uintptr_t)OFDlsym(handle, "init_plugin");
	initPlugin = (init_plugin_t)(uintptr_t)OFDlSym(handle, "init_plugin");
	if (initPlugin == (init_plugin_t)0 || (plugin = initPlugin()) == nil) {
		OFDlclose(handle);
		OFDlClose(handle);
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
	}

	plugin->_pluginHandle = handle;
	return plugin;
}
134
135
136
137
138
139
140
141

142
143
134
135
136
137
138
139
140

141
142
143







-
+



- (void)dealloc
{
	OFPluginHandle h = _pluginHandle;

	[super dealloc];

	OFDlclose(h);
	OFDlClose(h);
}
@end

Modified src/OFSPXSocket.m from [c64514d206] to [b23786191d].

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
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







-
+



















-
+







#endif

	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException exceptionWithSocket: self];

	if ((_socket = socket(address->sockaddr.ipx.sipx_family,
	    SOCK_SEQPACKET | SOCK_CLOEXEC, NSPROTO_SPX)) == INVALID_SOCKET) {
		*errNo = of_socket_errno();
		*errNo = OFSocketErrNo();
		return false;
	}

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

	return true;
}

- (bool)of_connectSocketToAddress: (const OFSocketAddress *)address
			    errNo: (int *)errNo
{
	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (connect(_socket, &address->sockaddr.sockaddr,
	    address->length) != 0) {
		*errNo = of_socket_errno();
		*errNo = OFSocketErrNo();
		return false;
	}

	return true;
}

- (void)of_closeSocket
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

356
357

358
359
360
361
362
363
364
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356

357
358
359
360
361
362
363
364







-
+









-
+














-
+

-
+








	if ((_socket = socket(address.sockaddr.sockaddr.sa_family,
	    SOCK_SEQPACKET | SOCK_CLOEXEC, NSPROTO_SPX)) == INVALID_SOCKET)
		@throw [OFBindFailedException
		    exceptionWithPort: port
			   packetType: SPX_PACKET_TYPE
			       socket: self
				errNo: of_socket_errno()];
				errNo: OFSocketErrNo()];

	_canBlock = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC)
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

	if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) {
		int errNo = of_socket_errno();
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithPort: port
						     packetType: SPX_PACKET_TYPE
							 socket: self
							  errNo: errNo];
	}

	memset(&address, 0, sizeof(address));
	address.family = OFSocketAddressFamilyIPX;
	address.length = (socklen_t)sizeof(address.sockaddr);

	if (of_getsockname(_socket, &address.sockaddr.sockaddr,
	if (OFGetSockName(_socket, &address.sockaddr.sockaddr,
	    &address.length) != 0) {
		int errNo = of_socket_errno();
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithPort: port
						     packetType: SPX_PACKET_TYPE
							 socket: self

Modified src/OFSPXStreamSocket.m from [6ebec05570] to [e65181dea2].

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
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







-
+



















-
+







#endif

	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException exceptionWithSocket: self];

	if ((_socket = socket(address->sockaddr.ipx.sipx_family,
	    SOCK_SEQPACKET | SOCK_CLOEXEC, NSPROTO_SPX)) == INVALID_SOCKET) {
		*errNo = of_socket_errno();
		*errNo = OFSocketErrNo();
		return false;
	}

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

	return true;
}

- (bool)of_connectSocketToAddress: (const OFSocketAddress *)address
			    errNo: (int *)errNo
{
	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (connect(_socket, &address->sockaddr.sockaddr,
	    address->length) != 0) {
		*errNo = of_socket_errno();
		*errNo = OFSocketErrNo();
		return false;
	}

	return true;
}

- (void)of_closeSocket
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

358
359

360
361
362
363
364
365
366
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

357
358

359
360
361
362
363
364
365
366







-
+









-
+














-
+

-
+








	if ((_socket = socket(address.sockaddr.sockaddr.sa_family,
	    SOCK_STREAM | SOCK_CLOEXEC, NSPROTO_SPX)) == INVALID_SOCKET)
		@throw [OFBindFailedException
		    exceptionWithPort: port
			   packetType: SPX_PACKET_TYPE
			       socket: self
				errNo: of_socket_errno()];
				errNo: OFSocketErrNo()];

	_canBlock = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC)
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

	if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) {
		int errNo = of_socket_errno();
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithPort: port
						     packetType: SPX_PACKET_TYPE
							 socket: self
							  errNo: errNo];
	}

	memset(&address, 0, sizeof(address));
	address.family = OFSocketAddressFamilyIPX;
	address.length = (socklen_t)sizeof(address.sockaddr);

	if (of_getsockname(_socket, &address.sockaddr.sockaddr,
	if (OFGetSockName(_socket, &address.sockaddr.sockaddr,
	    &address.length) != 0) {
		int errNo = of_socket_errno();
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithPort: port
						     packetType: SPX_PACKET_TYPE
							 socket: self

Modified src/OFSelectKernelEventObserver.m from [542d396da8] to [c54e00c28f].

229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243







-
+







	events = select(_maxFD + 1, &readFDs, &writeFDs, NULL,
	    (timeInterval != -1 ? &timeout : NULL));
#endif

	if (events < 0)
		@throw [OFObserveFailedException
		    exceptionWithObserver: self
				    errNo: of_socket_errno()];
				    errNo: OFSocketErrNo()];

#ifdef OF_AMIGAOS
	if (execSignalMask != 0 &&
	    [_delegate respondsToSelector: @selector(execSignalWasReceived:)])
		[_delegate execSignalWasReceived: execSignalMask];
#else
	if (FD_ISSET(_cancelFD[0], &readFDs)) {

Modified src/OFSequencedPacketSocket.m from [579289a3de] to [7fb3ae7788].

49
50
51
52
53
54
55
56

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

56
57
58
59
60
61
62
63







-
+







@synthesize listening = _listening, delegate = _delegate;

+ (void)initialize
{
	if (self != [OFSequencedPacketSocket class])
		return;

	if (!of_socket_init())
	if (!OFSocketInit())
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}

+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109







-
+







- (int)of_socketError
{
	int errNo;
	socklen_t len = sizeof(errNo);

	if (getsockopt(_socket, SOL_SOCKET, SO_ERROR, (char *)&errNo,
	    &len) != 0)
		return of_socket_errno();
		return OFSocketErrNo();

	return errNo;
}
#endif

- (id)copy
{
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
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







-
+



















-
+








-
+







	_canBlock = canBlock;
#elif defined(OF_WINDOWS)
	u_long v = canBlock;

	if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR)
		@throw [OFSetOptionFailedException
		    exceptionWithObject: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

	_canBlock = canBlock;
#else
	OF_UNRECOGNIZED_SELECTOR
#endif
}

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

	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

#ifndef OF_WINDOWS
	if ((ret = recv(_socket, buffer, length, 0)) < 0)
		@throw [OFReadFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#else
	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if ((ret = recv(_socket, buffer, (int)length, 0)) < 0)
		@throw [OFReadFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#endif

	return ret;
}

- (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length
{
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
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







-
+











-
+







		@throw [OFOutOfRangeException exception];

	if ((bytesWritten = send(_socket, (void *)buffer, length, 0)) < 0)
		@throw [OFWriteFailedException
		    exceptionWithObject: self
			requestedLength: length
			   bytesWritten: 0
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#else
	int bytesWritten;

	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if ((bytesWritten = send(_socket, buffer, (int)length, 0)) < 0)
		@throw [OFWriteFailedException
		    exceptionWithObject: self
			requestedLength: length
			   bytesWritten: 0
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#endif

	if ((size_t)bytesWritten != length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length
						      bytesWritten: bytesWritten
							     errNo: 0];
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321







-
+







	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (listen(_socket, backlog) == -1)
		@throw [OFListenFailedException
		    exceptionWithSocket: self
				backlog: backlog
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

	_listening = true;
}

- (instancetype)accept
{
	OFSequencedPacketSocket *client =
332
333
334
335
336
337
338
339

340
341
342
343
344
345
346

347
348
349
350
351
352
353

354
355
356
357
358
359
360
332
333
334
335
336
337
338

339
340
341
342
343
344
345

346
347
348
349
350
351
352

353
354
355
356
357
358
359
360







-
+






-
+






-
+







#if defined(HAVE_PACCEPT) && defined(SOCK_CLOEXEC)
	if ((client->_socket = paccept(_socket,
	    &client->_remoteAddress.sockaddr.sockaddr,
	    &client->_remoteAddress.length, NULL, SOCK_CLOEXEC)) ==
	    INVALID_SOCKET)
		@throw [OFAcceptFailedException
		    exceptionWithSocket: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#elif defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC)
	if ((client->_socket = accept4(_socket,
	    &client->_remoteAddress.sockaddr.sockaddr,
	    &client->_remoteAddress.length, SOCK_CLOEXEC)) == INVALID_SOCKET)
		@throw [OFAcceptFailedException
		    exceptionWithSocket: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#else
	if ((client->_socket = accept(_socket,
	    &client->_remoteAddress.sockaddr.sockaddr,
	    &client->_remoteAddress.length)) == INVALID_SOCKET)
		@throw [OFAcceptFailedException
		    exceptionWithSocket: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

# if defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	if ((flags = fcntl(client->_socket, F_GETFD, 0)) != -1)
		fcntl(client->_socket, F_SETFD, flags | FD_CLOEXEC);
# endif
#endif

Modified src/OFSocket+Private.h from [bfa027c35a] to [f72f312a8d].

54
55
56
57
58
59
60
61

62
63

64
65
66
67
68
69
70
54
55
56
57
58
59
60

61
62

63
64
65
66
67
68
69
70







-
+

-
+







# endif
# include <sys/filio.h>
# define closesocket(sock) CloseSocket(sock)
# define ioctlsocket(fd, req, arg) IoctlSocket(fd, req, arg)
# define hstrerror(err) "unknown (no hstrerror)"
# define SOCKET_ERROR -1
# if defined(OF_HAVE_THREADS) && !defined(OF_MORPHOS)
#  define SocketBase ((struct Library *)OFTLSKeyGet(of_socket_base_key))
#  define SocketBase ((struct Library *)OFTLSKeyGet(OFSocketBaseKey))
#  ifdef OF_AMIGAOS4
#   define ISocket ((struct SocketIFace *)OFTLSKeyGet(of_socket_interface_key))
#   define ISocket ((struct SocketIFace *)OFTLSKeyGet(OFSocketInterfaceKey))
#  endif
# endif
# ifdef OF_MORPHOS
typedef uint32_t in_addr_t;
# endif
#elif !defined(OF_WINDOWS) && !defined(OF_WII)
# define closesocket(sock) close(sock)

Modified src/OFSocket.h from [49c6656be8] to [4e8739b8a5].

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
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







-
+

-
+

-
+

-
+




-
+

-
+







 *
 * @param address The address on which to get the IPX node
 * @param node A byte array to store the IPX node of the address
 */
extern void OFSocketAddressIPXNode(const OFSocketAddress *_Nonnull address,
    unsigned char node[_Nonnull IPX_NODE_LEN]);

extern bool of_socket_init(void);
extern bool OFSocketInit(void);
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
extern void of_socket_deinit(void);
extern void OFSocketDeinit(void);
#endif
extern int of_socket_errno(void);
extern int OFSocketErrNo(void);
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
extern int of_getsockname(OFSocketHandle sock, struct sockaddr *restrict addr,
extern int OFGetSockName(OFSocketHandle sock, struct sockaddr *restrict addr,
    socklen_t *restrict addrLen);
#endif

#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
extern OFTLSKey of_socket_base_key;
extern OFTLSKey OFSocketBaseKey;
# ifdef OF_AMIGAOS4
extern OFTLSKey of_socket_interface_key;
extern OFTLSKey OFSocketInterfaceKey;
# endif
#endif
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFSocket.m from [3ac6ff523b] to [941bbd3cbe].

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
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







-
+

-
+












-
+



-
+







#endif
#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static bool initSuccessful = false;
#endif

#ifdef OF_AMIGAOS
# if defined(OF_HAVE_THREADS) && !defined(OF_MORPHOS)
OFTLSKey of_socket_base_key;
OFTLSKey OFSocketBaseKey;
#  ifdef OF_AMIGAOS4
OFTLSKey of_socket_interface_key;
OFTLSKey OFSocketInterfaceKey;
#  endif
# else
struct Library *SocketBase;
#  ifdef OF_AMIGAOS4
struct SocketIFace *ISocket = NULL;
#  endif
# endif
#endif

#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
OF_CONSTRUCTOR()
{
	if (OFTLSKeyNew(&of_socket_base_key) != 0)
	if (OFTLSKeyNew(&OFSocketBaseKey) != 0)
		@throw [OFInitializationFailedException exception];

# ifdef OF_AMIGAOS4
	if (OFTLSKeyNew(&of_socket_interface_key) != 0)
	if (OFTLSKeyNew(&OFSocketInterfaceKey) != 0)
		@throw [OFInitializationFailedException exception];
# endif
}
#endif

#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static void
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
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
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
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237







-
+













-
+

-
+














-
+








-
+












-
+

-
+

-
+
-










-
+







	if (SocketBase != NULL)
		CloseLibrary(SocketBase);
# endif
}
#endif

bool
of_socket_init(void)
OFSocketInit(void)
{
#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
	static OFOnceControl onceControl = OFOnceControlInitValue;
	OFOnce(&onceControl, init);

	return initSuccessful;
#else
	struct Library *socketBase;
# ifdef OF_AMIGAOS4
	struct SocketIFace *socketInterface;
# endif

# ifdef OF_AMIGAOS4
	if ((socketInterface = OFTLSKeyGet(of_socket_interface_key)) != NULL)
	if ((socketInterface = OFTLSKeyGet(OFSocketInterfaceKey)) != NULL)
# else
	if ((socketBase = OFTLSKeyGet(of_socket_base_key)) != NULL)
	if ((socketBase = OFTLSKeyGet(OFSocketBaseKey)) != NULL)
# endif
		return true;

	if ((socketBase = OpenLibrary("bsdsocket.library", 4)) == NULL)
		return false;

# ifdef OF_AMIGAOS4
	if ((socketInterface = (struct SocketIFace *)
	    GetInterface(socketBase, "main", 1, NULL)) == NULL) {
		CloseLibrary(socketBase);
		return false;
	}
# endif

	if (OFTLSKeySet(of_socket_base_key, socketBase) != 0) {
	if (OFTLSKeySet(OFSocketBaseKey, socketBase) != 0) {
		CloseLibrary(socketBase);
# ifdef OF_AMIGAOS4
		DropInterface((struct Interface *)socketInterface);
# endif
		return false;
	}

# ifdef OF_AMIGAOS4
	if (OFTLSKeySet(of_socket_interface_key, socketInterface) != 0) {
	if (OFTLSKeySet(OFSocketInterfaceKey, socketInterface) != 0) {
		CloseLibrary(socketBase);
		DropInterface((struct Interface *)socketInterface);
		return false;
	}
# endif

	return true;
#endif
}

#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
void
of_socket_deinit(void)
OFSocketDeinit(void)
{
	struct Library *socketBase = OFTLSKeyGet(of_socket_base_key);
	struct Library *socketBase = OFTLSKeyGet(OFSocketBaseKey);
# ifdef OF_AMIGAOS4
	struct SocketIFace *socketInterface =
	struct SocketIFace *socketInterface = OFTLSKeyGet(OFSocketInterfaceKey);
	    OFTLSKeyGet(of_socket_interface_key);

	if (socketInterface != NULL)
		DropInterface((struct Interface *)socketInterface);
# endif
	if (socketBase != NULL)
		CloseLibrary(socketBase);
}
#endif

int
of_socket_errno()
OFSocketErrNo()
{
#if defined(OF_WINDOWS)
	switch (WSAGetLastError()) {
	case WSAEACCES:
		return EACCES;
	case WSAEADDRINUSE:
		return EADDRINUSE;
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339







-
+







#else
	return errno;
#endif
}

#ifndef OF_WII
int
of_getsockname(OFSocketHandle sock, struct sockaddr *restrict addr,
OFGetSockName(OFSocketHandle sock, struct sockaddr *restrict addr,
    socklen_t *restrict addrLen)
{
	int ret;

# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS))
	[mutex lock];
# endif

Modified src/OFStdIOStream.h from [cc0a782d1d] to [56543eac46].

27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41







-
+







@class OFColor;

/**
 * @class OFStdIOStream OFStdIOStream.h ObjFW/OFStdIOStream.h
 *
 * @brief A class for providing standard input, output and error as OFStream.
 *
 * The global variables @ref of_stdin, @ref of_stdout and @ref of_stderr are
 * The global variables @ref OFStdIn, @ref OFStdOut and @ref OFStdErr are
 * instances of this class and need no initialization.
 */
#ifdef OF_STDIO_STREAM_WIN32_CONSOLE_H
OF_SUBCLASSING_RESTRICTED
#endif
@interface OFStdIOStream: OFStream
#if !defined(OF_WINDOWS) && !defined(OF_AMIGAOS)
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
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







-
+




-
+




-
+


-
+




-
+





extern "C" {
#endif
/** @file */

/**
 * @brief The standard input as an OFStream.
 */
extern OFStdIOStream *_Nullable of_stdin;
extern OFStdIOStream *_Nullable OFStdIn;

/**
 * @brief The standard output as an OFStream.
 */
extern OFStdIOStream *_Nullable of_stdout;
extern OFStdIOStream *_Nullable OFStdOut;

/**
 * @brief The standard error as an OFStream.
 */
extern OFStdIOStream *_Nullable of_stderr;
extern OFStdIOStream *_Nullable OFStdErr;

/**
 * @brief Log the specified printf-style format to @ref of_stderr.
 * @brief Log the specified printf-style format to @ref OFStdErr.
 *
 * This prefixes the output with the date, timestamp, process name and PID and
 * allows `%@` as a printf-style formatted to print objects.
 */
extern void of_log(OFConstantString *format, ...);
extern void OFLog(OFConstantString *format, ...);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFStdIOStream.m from [6e155b4549] to [a9dd0b73a2].

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
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







-
-
-
+
+
+




-
-
-
+
+
+




-
+



















-
-
+
+







void
_reference_to_OFWin32ConsoleStdIOStream(void)
{
	[OFWin32ConsoleStdIOStream class];
}
#endif

OFStdIOStream *of_stdin = nil;
OFStdIOStream *of_stdout = nil;
OFStdIOStream *of_stderr = nil;
OFStdIOStream *OFStdIn = nil;
OFStdIOStream *OFStdOut = nil;
OFStdIOStream *OFStdErr = nil;

#ifdef OF_AMIGAOS
OF_DESTRUCTOR()
{
	[of_stdin dealloc];
	[of_stdout dealloc];
	[of_stderr dealloc];
	[OFStdIn dealloc];
	[OFStdOut dealloc];
	[OFStdErr dealloc];
}
#endif

void
of_log(OFConstantString *format, ...)
OFLog(OFConstantString *format, ...)
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *date;
	OFString *dateString, *me, *msg;
	va_list arguments;

	date = [OFDate date];
	dateString = [date localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];
#ifdef OF_HAVE_FILES
	me = [OFApplication programName].lastPathComponent;
#else
	me = [OFApplication programName];
#endif

	va_start(arguments, format);
	msg = [[[OFString alloc] initWithFormat: format
				      arguments: arguments] autorelease];
	va_end(arguments);

	[of_stderr writeFormat: @"[%@.%03d %@(%d)] %@\n", dateString,
				date.microsecond / 1000, me, getpid(), msg];
	[OFStdErr writeFormat: @"[%@.%03d %@(%d)] %@\n", dateString,
			       date.microsecond / 1000, me, getpid(), msg];

	objc_autoreleasePoolPop(pool);
}

#ifdef HAVE_ISATTY
static int
colorToANSI(OFColor *color)
149
150
151
152
153
154
155
156
157

158
159

160
161
162

163
164
165
166
167
168
169
149
150
151
152
153
154
155


156
157

158
159
160

161
162
163
164
165
166
167
168







-
-
+

-
+


-
+







	if (self != [OFStdIOStream class])
		return;

# ifndef OF_AMIGAOS
	int fd;

	if ((fd = fileno(stdin)) >= 0)
		of_stdin = [[OFStdIOStream alloc]
		    of_initWithFileDescriptor: fd];
		OFStdIn = [[OFStdIOStream alloc] of_initWithFileDescriptor: fd];
	if ((fd = fileno(stdout)) >= 0)
		of_stdout = [[OFStdIOStream alloc]
		OFStdOut = [[OFStdIOStream alloc]
		    of_initWithFileDescriptor: fd];
	if ((fd = fileno(stderr)) >= 0)
		of_stderr = [[OFStdIOStream alloc]
		OFStdErr = [[OFStdIOStream alloc]
		    of_initWithFileDescriptor: fd];
# else
	BPTR input, output, error;
	bool inputClosable = false, outputClosable = false,
	    errorClosable = false;

	input = Input();
181
182
183
184
185
186
187
188
189
190
191
192
193






194
195
196
197
198
199
200
180
181
182
183
184
185
186






187
188
189
190
191
192
193
194
195
196
197
198
199







-
-
-
-
-
-
+
+
+
+
+
+







	}

	if (error == 0) {
		error = Open("*", MODE_OLDFILE);
		errorClosable = true;
	}

	of_stdin = [[OFStdIOStream alloc] of_initWithHandle: input
						   closable: inputClosable];
	of_stdout = [[OFStdIOStream alloc] of_initWithHandle: output
						    closable: outputClosable];
	of_stderr = [[OFStdIOStream alloc] of_initWithHandle: error
						    closable: errorClosable];
	OFStdIn = [[OFStdIOStream alloc] of_initWithHandle: input
						  closable: inputClosable];
	OFStdOut = [[OFStdIOStream alloc] of_initWithHandle: output
						   closable: outputClosable];
	OFStdErr = [[OFStdIOStream alloc] of_initWithHandle: error
						   closable: errorClosable];
# endif
}
#endif

- (instancetype)init
{
	OF_INVALID_INIT_METHOD

Modified src/OFStreamSocket.m from [5c58a6db92] to [0813befdb2].

47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61







-
+







@synthesize listening = _listening;

+ (void)initialize
{
	if (self != [OFStreamSocket class])
		return;

	if (!of_socket_init())
	if (!OFSocketInit())
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}

+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
+








-
+







		@throw [OFNotOpenException exceptionWithObject: self];

#ifndef OF_WINDOWS
	if ((ret = recv(_socket, buffer, length, 0)) < 0)
		@throw [OFReadFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#else
	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if ((ret = recv(_socket, buffer, (int)length, 0)) < 0)
		@throw [OFReadFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#endif

	if (ret == 0)
		_atEndOfStream = true;

	return ret;
}
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
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







-
+











-
+

















-
+







		@throw [OFOutOfRangeException exception];

	if ((bytesWritten = send(_socket, (void *)buffer, length, 0)) < 0)
		@throw [OFWriteFailedException
		    exceptionWithObject: self
			requestedLength: length
			   bytesWritten: 0
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#else
	int bytesWritten;

	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if ((bytesWritten = send(_socket, buffer, (int)length, 0)) < 0)
		@throw [OFWriteFailedException
		    exceptionWithObject: self
			requestedLength: length
			   bytesWritten: 0
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#endif

	return (size_t)bytesWritten;
}

#if defined(OF_WINDOWS) || defined(OF_AMIGAOS)
- (void)setCanBlock: (bool)canBlock
{
# ifdef OF_WINDOWS
	u_long v = canBlock;
# else
	char v = canBlock;
# endif

	if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR)
		@throw [OFSetOptionFailedException
		    exceptionWithObject: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

	_canBlock = canBlock;
}
#endif

- (int)fileDescriptorForReading
{
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
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







-
+



















-
+







- (int)of_socketError
{
	int errNo;
	socklen_t len = sizeof(errNo);

	if (getsockopt(_socket, SOL_SOCKET, SO_ERROR, (char *)&errNo,
	    &len) != 0)
		return of_socket_errno();
		return OFSocketErrNo();

	return errNo;
}
#endif

- (void)listen
{
	[self listenWithBacklog: SOMAXCONN];
}

- (void)listenWithBacklog: (int)backlog
{
	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (listen(_socket, backlog) == -1)
		@throw [OFListenFailedException
		    exceptionWithSocket: self
				backlog: backlog
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

	_listening = true;
}

- (instancetype)accept
{
	OFStreamSocket *client = [[[[self class] alloc] init] autorelease];
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270

271
272
273
274
275
276
277

278
279
280
281
282
283
284
256
257
258
259
260
261
262

263
264
265
266
267
268
269

270
271
272
273
274
275
276

277
278
279
280
281
282
283
284







-
+






-
+






-
+







#if defined(HAVE_PACCEPT) && defined(SOCK_CLOEXEC)
	if ((client->_socket = paccept(_socket,
	    &client->_remoteAddress.sockaddr.sockaddr,
	    &client->_remoteAddress.length, NULL, SOCK_CLOEXEC)) ==
	    INVALID_SOCKET)
		@throw [OFAcceptFailedException
		    exceptionWithSocket: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#elif defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC)
	if ((client->_socket = accept4(_socket,
	    &client->_remoteAddress.sockaddr.sockaddr,
	    &client->_remoteAddress.length, SOCK_CLOEXEC)) == INVALID_SOCKET)
		@throw [OFAcceptFailedException
		    exceptionWithSocket: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
#else
	if ((client->_socket = accept(_socket,
	    &client->_remoteAddress.sockaddr.sockaddr,
	    &client->_remoteAddress.length)) == INVALID_SOCKET)
		@throw [OFAcceptFailedException
		    exceptionWithSocket: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

# if defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	if ((flags = fcntl(client->_socket, F_GETFD, 0)) != -1)
		fcntl(client->_socket, F_SETFD, flags | FD_CLOEXEC);
# endif
#endif

Modified src/OFString+JSONParsing.m from [5b4983e183] to [fd3673a355].

203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
203
204
205
206
207
208
209


210
211
212
213
214
215
216
217







-
-
+







				if ((c1 & 0xFC00) == 0xDC00) {
					OFFreeMemory(buffer);
					return nil;
				}

				/* Normal character */
				if ((c1 & 0xFC00) != 0xD800) {
					l = of_string_utf8_encode(c1,
					    buffer + i);
					l = OFUTF8StringEncode(c1, buffer + i);
					if (l == 0) {
						OFFreeMemory(buffer);
						return nil;
					}

					i += l;
					*pointer += 5;
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243







-
+







					OFFreeMemory(buffer);
					return nil;
				}

				c = (((c1 & 0x3FF) << 10) |
				    (c2 & 0x3FF)) + 0x10000;

				l = of_string_utf8_encode(c, buffer + i);
				l = OFUTF8StringEncode(c, buffer + i);
				if (l == 0) {
					OFFreeMemory(buffer);
					return nil;
				}

				i += l;
				*pointer += 11;
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339







-
+







			if ((c1 & 0xFC00) == 0xDC00) {
				OFFreeMemory(buffer);
				return nil;
			}

			/* Normal character */
			if ((c1 & 0xFC00) != 0xD800) {
				l = of_string_utf8_encode(c1, buffer + i);
				l = OFUTF8StringEncode(c1, buffer + i);
				if (l == 0) {
					OFFreeMemory(buffer);
					return nil;
				}

				i += l;
				*pointer += 5;
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364







-
+







			if (c2 == 0xFFFF) {
				OFFreeMemory(buffer);
				return nil;
			}

			c = (((c1 & 0x3FF) << 10) | (c2 & 0x3FF)) + 0x10000;

			l = of_string_utf8_encode(c, buffer + i);
			l = OFUTF8StringEncode(c, buffer + i);
			if (l == 0) {
				OFFreeMemory(buffer);
				return nil;
			}

			i += l;
			*pointer += 11;

Modified src/OFString+URLEncoding.m from [ce8d6c0fa7] to [136d9c5f3e].

46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60







-
+







		if (characterIsMember(allowedCharacters,
		    @selector(characterIsMember:), c))
			[ret appendCharacters: &c length: 1];
		else {
			char buffer[4];
			size_t bufferLen;

			if ((bufferLen = of_string_utf8_encode(c, buffer)) == 0)
			if ((bufferLen = OFUTF8StringEncode(c, buffer)) == 0)
				@throw [OFInvalidEncodingException exception];

			for (size_t j = 0; j < bufferLen; j++) {
				unsigned char byte = buffer[j];
				unsigned char high = byte >> 4;
				unsigned char low = byte & 0x0F;
				char escaped[3];

Modified src/OFString+XMLUnescaping.m from [0a903f9009] to [0941da3dc0].

60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74







-
+







			if (entity[i] >= '0' && entity[i] <= '9')
				c = (c * 10) + (entity[i] - '0');
			else
				return nil;
		}
	}

	if ((i = of_string_utf8_encode(c, buffer)) == 0)
	if ((i = OFUTF8StringEncode(c, buffer)) == 0)
		return nil;
	buffer[i] = 0;

	return [OFString stringWithUTF8String: buffer length: i];
}

static OFString *

Modified src/OFString.h from [7a23f6e323] to [068370b7c7].

1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297




1298
1299
1300
1301
1302
1303
1304
1287
1288
1289
1290
1291
1292
1293




1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304







-
-
-
-
+
+
+
+







 * @brief Returns the name of the specified OFStringEncoding.
 *
 * @param encoding The encoding for which to return the name
 * @return The name of the specified OFStringEncoding
 */
extern OFString *_Nullable OFStringEncodingName(OFStringEncoding encoding);

extern size_t of_string_utf8_encode(OFUnichar, char *);
extern ssize_t of_string_utf8_decode(const char *, size_t, OFUnichar *);
extern size_t of_string_utf16_length(const OFChar16 *);
extern size_t of_string_utf32_length(const OFChar32 *);
extern size_t OFUTF8StringEncode(OFUnichar, char *);
extern ssize_t OFUTF8StringDecode(const char *, size_t, OFUnichar *);
extern size_t OFUTF16StringLength(const OFChar16 *);
extern size_t OFUTF32StringLength(const OFChar32 *);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

#include "OFConstantString.h"

Modified src/OFString.m from [3ff34c1351] to [afb8450add].

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
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







-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+







    of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options
			       depth: (size_t)depth;
@end

@interface OFStringPlaceholder: OFString
@end

extern bool of_unicode_to_iso_8859_2(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToISO8859_2(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_iso_8859_3(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToISO8859_3(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_iso_8859_15(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToISO8859_15(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_windows_1251(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToWindows1251(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_windows_1252(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToWindows1252(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_codepage_437(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToCodepage437(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_codepage_850(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToCodepage850(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_codepage_858(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToCodepage858(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_mac_roman(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToMacRoman(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_koi8_r(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToKOI8R(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_koi8_u(const OFUnichar *, unsigned char *,
extern bool OFUnicodeToKOI8U(const OFUnichar *, unsigned char *,
    size_t, bool);

/* References for static linking */
void
_references_to_categories_of_OFString(void)
{
	_OFString_CryptographicHashing_reference = 1;
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251







-
+







		return @"autodetect";
	}

	return nil;
}

size_t
of_string_utf8_encode(OFUnichar character, char *buffer)
OFUTF8StringEncode(OFUnichar character, char *buffer)
{
	if (character < 0x80) {
		buffer[0] = character;
		return 1;
	} else if (character < 0x800) {
		buffer[0] = 0xC0 | (character >> 6);
		buffer[1] = 0x80 | (character & 0x3F);
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277







-
+







		return 4;
	}

	return 0;
}

ssize_t
of_string_utf8_decode(const char *buffer_, size_t length, OFUnichar *ret)
OFUTF8StringDecode(const char *buffer_, size_t length, OFUnichar *ret)
{
	const unsigned char *buffer = (const unsigned char *)buffer_;

	if (!(*buffer & 0x80)) {
		*ret = buffer[0];
		return 1;
	}
313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338







-
+










-
+







		return 4;
	}

	return 0;
}

size_t
of_string_utf16_length(const OFChar16 *string)
OFUTF16StringLength(const OFChar16 *string)
{
	size_t length = 0;

	while (*string++ != 0)
		length++;

	return length;
}

size_t
of_string_utf32_length(const OFChar32 *string)
OFUTF32StringLength(const OFChar32 *string)
{
	size_t length = 0;

	while (*string++ != 0)
		length++;

	return length;
895
896
897
898
899
900
901
902

903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918

919
920
921
922
923
924
925
926
927
928
929
930
931
932

933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948

949
950
951
952
953
954
955
895
896
897
898
899
900
901

902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917

918
919
920
921
922
923
924
925
926
927
928
929
930
931

932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947

948
949
950
951
952
953
954
955







-
+















-
+













-
+















-
+







{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithUTF16String: (const OFChar16 *)string
{
	return [self initWithUTF16String: string
				  length: of_string_utf16_length(string)
				  length: OFUTF16StringLength(string)
			       byteOrder: OFByteOrderNative];
}

- (instancetype)initWithUTF16String: (const OFChar16 *)string
			     length: (size_t)length
{
	return [self initWithUTF16String: string
				  length: length
			       byteOrder: OFByteOrderNative];
}

- (instancetype)initWithUTF16String: (const OFChar16 *)string
			  byteOrder: (OFByteOrder)byteOrder
{
	return [self initWithUTF16String: string
				  length: of_string_utf16_length(string)
				  length: OFUTF16StringLength(string)
			       byteOrder: byteOrder];
}

- (instancetype)initWithUTF16String: (const OFChar16 *)string
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithUTF32String: (const OFChar32 *)string
{
	return [self initWithUTF32String: string
				  length: of_string_utf32_length(string)
				  length: OFUTF32StringLength(string)
			       byteOrder: OFByteOrderNative];
}

- (instancetype)initWithUTF32String: (const OFChar32 *)string
			     length: (size_t)length
{
	return [self initWithUTF32String: string
				  length: length
			       byteOrder: OFByteOrderNative];
}

- (instancetype)initWithUTF32String: (const OFChar32 *)string
			  byteOrder: (OFByteOrder)byteOrder
{
	return [self initWithUTF32String: string
				  length: of_string_utf32_length(string)
				  length: OFUTF32StringLength(string)
			       byteOrder: byteOrder];
}

- (instancetype)initWithUTF32String: (const OFChar32 *)string
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
1124
1125
1126
1127
1128
1129
1130
1131

1132
1133
1134
1135
1136
1137
1138
1139
1124
1125
1126
1127
1128
1129
1130

1131

1132
1133
1134
1135
1136
1137
1138







-
+
-








	switch (encoding) {
	case OFStringEncodingUTF8:;
		size_t j = 0;

		for (i = 0; i < length; i++) {
			char buffer[4];
			size_t len = of_string_utf8_encode(characters[i],
			size_t len = OFUTF8StringEncode(characters[i], buffer);
			    buffer);

			/*
			 * Check for one more than the current index, as we
			 * need one for the terminating zero.
			 */
			if (j + len >= maxLength)
				@throw [OFOutOfRangeException exception];
1197
1198
1199
1200
1201
1202
1203
1204
1205


1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218


1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231


1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256

1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295

1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309


1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322


1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335


1336
1337
1338
1339
1340
1341
1342
1196
1197
1198
1199
1200
1201
1202


1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215


1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228


1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241

1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267

1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293

1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306


1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319


1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332


1333
1334
1335
1336
1337
1338
1339
1340
1341







-
-
+
+











-
-
+
+











-
-
+
+











-
+












-
+












-
+












-
+












-
+












-
-
+
+











-
-
+
+











-
-
+
+








		return length;
#ifdef HAVE_ISO_8859_2
	case OFStringEncodingISO8859_2:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_iso_8859_2(characters,
		    (unsigned char *)cString, length, lossy))
		if (!OFUnicodeToISO8859_2(characters, (unsigned char *)cString,
		    length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_ISO_8859_3
	case OFStringEncodingISO8859_3:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_iso_8859_3(characters,
		    (unsigned char *)cString, length, lossy))
		if (!OFUnicodeToISO8859_3(characters, (unsigned char *)cString,
		    length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_ISO_8859_15
	case OFStringEncodingISO8859_15:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_iso_8859_15(characters,
		    (unsigned char *)cString, length, lossy))
		if (!OFUnicodeToISO8859_15(characters, (unsigned char *)cString,
		    length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_WINDOWS_1251
	case OFStringEncodingWindows1251:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_windows_1251(characters,
		if (!OFUnicodeToWindows1251(characters,
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_WINDOWS_1252
	case OFStringEncodingWindows1252:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_windows_1252(characters,
		if (!OFUnicodeToWindows1252(characters,
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_CODEPAGE_437
	case OFStringEncodingCodepage437:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_codepage_437(characters,
		if (!OFUnicodeToCodepage437(characters,
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_CODEPAGE_850
	case OFStringEncodingCodepage850:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_codepage_850(characters,
		if (!OFUnicodeToCodepage850(characters,
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_CODEPAGE_858
	case OFStringEncodingCodepage858:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_codepage_858(characters,
		if (!OFUnicodeToCodepage858(characters,
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_MAC_ROMAN
	case OFStringEncodingMacRoman:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_mac_roman(characters,
		    (unsigned char *)cString, length, lossy))
		if (!OFUnicodeToMacRoman(characters, (unsigned char *)cString,
		    length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_KOI8_R
	case OFStringEncodingKOI8R:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_koi8_r(characters,
		    (unsigned char *)cString, length, lossy))
		if (!OFUnicodeToKOI8R(characters, (unsigned char *)cString,
		    length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_KOI8_U
	case OFStringEncodingKOI8U:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_koi8_u(characters,
		    (unsigned char *)cString, length, lossy))
		if (!OFUnicodeToKOI8U(characters, (unsigned char *)cString,
		    length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
	default:
1462
1463
1464
1465
1466
1467
1468
1469

1470
1471
1472
1473
1474
1475
1476
1477
1461
1462
1463
1464
1465
1466
1467

1468

1469
1470
1471
1472
1473
1474
1475







-
+
-







		size_t length, UTF8StringLength = 0;

		characters = self.characters;
		length = self.length;

		for (size_t i = 0; i < length; i++) {
			char buffer[4];
			size_t len = of_string_utf8_encode(characters[i],
			size_t len = OFUTF8StringEncode(characters[i], buffer);
			    buffer);

			if (len == 0)
				@throw [OFInvalidEncodingException exception];

			UTF8StringLength += len;
		}

1616
1617
1618
1619
1620
1621
1622
1623

1624
1625

1626
1627
1628
1629
1630

1631
1632

1633
1634
1635
1636
1637
1638
1639
1614
1615
1616
1617
1618
1619
1620

1621
1622

1623
1624
1625
1626
1627

1628
1629

1630
1631
1632
1633
1634
1635
1636
1637







-
+

-
+




-
+

-
+







	minimumLength = (length > otherLength ? otherLength : length);

	for (size_t i = 0; i < minimumLength; i++) {
		OFUnichar c = characters[i];
		OFUnichar oc = otherCharacters[i];

#ifdef OF_HAVE_UNICODE_TABLES
		if (c >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) {
		if (c >> 8 < OFUnicodeCaseFoldingTableSize) {
			OFUnichar tc =
			    of_unicode_casefolding_table[c >> 8][c & 0xFF];
			    OFUnicodeCaseFoldingTable[c >> 8][c & 0xFF];

			if (tc)
				c = tc;
		}
		if (oc >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) {
		if (oc >> 8 < OFUnicodeCaseFoldingTableSize) {
			OFUnichar tc =
			    of_unicode_casefolding_table[oc >> 8][oc & 0xFF];
			    OFUnicodeCaseFoldingTable[oc >> 8][oc & 0xFF];

			if (tc)
				oc = tc;
		}
#else
		c = OFASCIIToUpper(c);
		oc = OFASCIIToUpper(oc);
2666
2667
2668
2669
2670
2671
2672
2673
2674


2675
2676
2677
2678
2679
2680


2681
2682
2683
2684
2685
2686
2687
2664
2665
2666
2667
2668
2669
2670


2671
2672
2673
2674
2675
2676


2677
2678
2679
2680
2681
2682
2683
2684
2685







-
-
+
+




-
-
+
+








	return [data autorelease];
}

#ifdef OF_HAVE_UNICODE_TABLES
- (OFString *)decomposedStringWithCanonicalMapping
{
	return decomposedString(self, of_unicode_decomposition_table,
	    OF_UNICODE_DECOMPOSITION_TABLE_SIZE);
	return decomposedString(self, OFUnicodeDecompositionTable,
	    OFUnicodeDecompositionTableSize);
}

- (OFString *)decomposedStringWithCompatibilityMapping
{
	return decomposedString(self, of_unicode_decomposition_compat_table,
	    OF_UNICODE_DECOMPOSITION_COMPAT_TABLE_SIZE);
	return decomposedString(self, OFUnicodeDecompositionCompatTable,
	    OFUnicodeDecompositionCompatTableSize);
}
#endif

#ifdef OF_WINDOWS
- (OFString *)stringByExpandingWindowsEnvironmentStrings
{
	if ([OFSystemInfo isWindowsNT]) {

Modified src/OFTCPSocket.h from [d5a780252d] to [9ae8ba1677].

209
210
211
212
213
214
215
216

217
218
219
220
221
209
210
211
212
213
214
215

216
217
218
219
220
221







-
+





 */
- (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern Class _Nullable of_tls_socket_class;
extern Class _Nullable OFTLSSocketClass;
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFTCPSocket.m from [006dac67c6] to [96bf5fcafe].

49
50
51
52
53
54
55
56

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

56
57
58
59
60
61
62
63







-
+







#import "OFNotImplementedException.h"
#import "OFNotOpenException.h"
#import "OFSetOptionFailedException.h"

static const OFRunLoopMode connectRunLoopMode =
    @"OFTCPSocketConnectRunLoopMode";

Class of_tls_socket_class = Nil;
Class OFTLSSocketClass = Nil;

static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;

@interface OFTCPSocket () <OFIPSocketAsyncConnecting>
@end

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
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







-
+




















-
+







#endif

	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException exceptionWithSocket: self];

	if ((_socket = socket(address->sockaddr.sockaddr.sa_family,
	    SOCK_STREAM | SOCK_CLOEXEC, 0)) == INVALID_SOCKET) {
		*errNo = of_socket_errno();
		*errNo = OFSocketErrNo();
		return false;
	}

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

	return true;
}

- (bool)of_connectSocketToAddress: (const OFSocketAddress *)address
			    errNo: (int *)errNo
{
	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	/* Cast needed for AmigaOS, where the argument is declared non-const */
	if (connect(_socket, (struct sockaddr *)&address->sockaddr.sockaddr,
	    address->length) != 0) {
		*errNo = of_socket_errno();
		*errNo = OFSocketErrNo();
		return false;
	}

	return true;
}

- (void)of_closeSocket
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353







-
+
















-
+








	if ((_socket = socket(address.sockaddr.sockaddr.sa_family,
	    SOCK_STREAM | SOCK_CLOEXEC, 0)) == INVALID_SOCKET)
		@throw [OFBindFailedException
		    exceptionWithHost: host
				 port: port
			       socket: self
				errNo: of_socket_errno()];
				errNo: OFSocketErrNo()];

	_canBlock = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

	setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR,
	    (char *)&one, (socklen_t)sizeof(one));

#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS)
	if (port != 0) {
#endif
		if (bind(_socket, &address.sockaddr.sockaddr,
		    address.length) != 0) {
			int errNo = of_socket_errno();
			int errNo = OFSocketErrNo();

			closesocket(_socket);
			_socket = INVALID_SOCKET;

			@throw [OFBindFailedException exceptionWithHost: host
								   port: port
								 socket: self
366
367
368
369
370
371
372
373
374


375
376
377
378
379
380
381
366
367
368
369
370
371
372


373
374
375
376
377
378
379
380
381







-
-
+
+








			if ((ret = bind(_socket, &address.sockaddr.sockaddr,
			    address.length)) == 0) {
				port = rnd;
				break;
			}

			if (of_socket_errno() != EADDRINUSE) {
				int errNo = of_socket_errno();
			if (OFSocketErrNo() != EADDRINUSE) {
				int errNo = OFSocketErrNo();

				closesocket(_socket);
				_socket = INVALID_SOCKET;

				@throw [OFBindFailedException
				    exceptionWithHost: host
						 port: port
391
392
393
394
395
396
397
398

399
400

401
402
403
404
405
406
407
391
392
393
394
395
396
397

398
399

400
401
402
403
404
405
406
407







-
+

-
+







	if (port > 0)
		return port;

#if !defined(OF_HPUX) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	memset(&address, 0, sizeof(address));

	address.length = (socklen_t)sizeof(address.sockaddr);
	if (of_getsockname(_socket, &address.sockaddr.sockaddr,
	if (OFGetSockName(_socket, &address.sockaddr.sockaddr,
	    &address.length) != 0) {
		int errNo = of_socket_errno();
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithHost: host
							   port: port
							 socket: self
438
439
440
441
442
443
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
438
439
440
441
442
443
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







-
+











-
+














-
+











-
+







{
	int v = sendsKeepAlives;

	if (setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE,
	    (char *)&v, (socklen_t)sizeof(v)) != 0)
		@throw [OFSetOptionFailedException
		    exceptionWithObject: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
}

- (bool)sendsKeepAlives
{
	int v;
	socklen_t len = sizeof(v);

	if (getsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE,
	    (char *)&v, &len) != 0 || len != sizeof(v))
		@throw [OFGetOptionFailedException
		    exceptionWithObject: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

	return v;
}
#endif

#ifndef OF_WII
- (void)setCanDelaySendingSegments: (bool)canDelaySendingSegments
{
	int v = !canDelaySendingSegments;

	if (setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY,
	    (char *)&v, (socklen_t)sizeof(v)) != 0)
		@throw [OFSetOptionFailedException
		    exceptionWithObject: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];
}

- (bool)canDelaySendingSegments
{
	int v;
	socklen_t len = sizeof(v);

	if (getsockopt(_socket, IPPROTO_TCP, TCP_NODELAY,
	    (char *)&v, &len) != 0 || len != sizeof(v))
		@throw [OFGetOptionFailedException
		    exceptionWithObject: self
				  errNo: of_socket_errno()];
				  errNo: OFSocketErrNo()];

	return !v;
}
#endif

- (void)close
{

Modified src/OFThread.m from [74f3661383] to [b51d41216b].

113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
+







		OFSetThreadName(
		    [name cStringWithEncoding: [OFLocale encoding]]);
	else
		OFSetThreadName(object_getClassName(thread));

#if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS)
	if (thread.supportsSockets)
		if (!of_socket_init())
		if (!OFSocketInit())
			@throw [OFInitializationFailedException
			    exceptionWithClass: thread.class];
#endif

	/*
	 * Nasty workaround for thread implementations which can't return a
	 * pointer on join, or don't have a way to exit a thread.
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155







-
+







	objc_autoreleasePoolPop((void *)(uintptr_t)-1);
#else
	objc_autoreleasePoolPop(thread->_pool);
#endif

#if defined(OF_AMIGAOS) && !defined(OF_MORPHOS) && defined(OF_HAVE_SOCKETS)
	if (thread.supportsSockets)
		of_socket_deinit();
		OFSocketDeinit();
#endif

	thread->_running = OFThreadStateWaitingForJoin;

	[thread release];
}

Modified src/OFUDPSocket.m from [c0ef3d326a] to [36850f3267].

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
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







-
+















-
+








	if ((_socket = socket(address->sockaddr.sockaddr.sa_family,
	    SOCK_DGRAM | SOCK_CLOEXEC | extraType, 0)) == INVALID_SOCKET)
		@throw [OFBindFailedException
		    exceptionWithHost: OFSocketAddressString(address)
				 port: OFSocketAddressPort(address)
			       socket: self
				errNo: of_socket_errno()];
				errNo: OFSocketErrNo()];

	_canBlock = true;

#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
	/* {} needed to avoid warning with Clang 10 if next #if is false. */
	if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) {
		fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
	}
#endif

#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS)
	if (OFSocketAddressPort(address) != 0) {
#endif
		if (bind(_socket, &address->sockaddr.sockaddr,
		    address->length) != 0) {
			int errNo = of_socket_errno();
			int errNo = OFSocketErrNo();

			closesocket(_socket);
			_socket = INVALID_SOCKET;

			@throw [OFBindFailedException
			    exceptionWithHost: OFSocketAddressString(address)
					 port: OFSocketAddressPort(address)
95
96
97
98
99
100
101
102
103


104
105
106
107
108
109
110
95
96
97
98
99
100
101


102
103
104
105
106
107
108
109
110







-
-
+
+








			if ((ret = bind(_socket, &address->sockaddr.sockaddr,
			    address->length)) == 0) {
				port = rnd;
				break;
			}

			if (of_socket_errno() != EADDRINUSE) {
				int errNo = of_socket_errno();
			if (OFSocketErrNo() != EADDRINUSE) {
				int errNo = OFSocketErrNo();
				OFString *host = OFSocketAddressString(address);
				uint16_t port = OFSocketAddressPort(port);

				closesocket(_socket);
				_socket = INVALID_SOCKET;

				@throw [OFBindFailedException
122
123
124
125
126
127
128
129

130
131

132
133
134
135
136
137
138
122
123
124
125
126
127
128

129
130

131
132
133
134
135
136
137
138







-
+

-
+







	if ((port = OFSocketAddressPort(address)) > 0)
		return port;

#if !defined(OF_HPUX) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	memset(address, 0, sizeof(*address));

	address->length = (socklen_t)sizeof(address->sockaddr);
	if (of_getsockname(_socket, &address->sockaddr.sockaddr,
	if (OFGetSockName(_socket, &address->sockaddr.sockaddr,
	    &address->length) != 0) {
		int errNo = of_socket_errno();
		int errNo = OFSocketErrNo();

		closesocket(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException
		    exceptionWithHost: OFSocketAddressString(address)
				 port: OFSocketAddressPort(address)

Modified src/OFURL.h from [82ad0a3397] to [c664c0ea4b].

363
364
365
366
367
368
369
370


371
372
373
374
375
376
377
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378







-
+
+







 */
+ (OFCharacterSet *)URLFragmentAllowedCharacterSet;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern bool of_url_is_ipv6_host(OFString *host);
extern bool OFURLIsIPv6Host(OFString *host);
extern void OFURLVerifyEscaped(OFString *, OFCharacterSet *);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

#import "OFMutableURL.h"

Modified src/OFURL.m from [a00286cb86] to [73a5f7c125].

103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117







-
+







	bool (*_characterIsMember)(id, SEL, OFUnichar);
}

- (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet;
@end

bool
of_url_is_ipv6_host(OFString *host)
OFURLIsIPv6Host(OFString *host)
{
	const char *UTF8String = host.UTF8String;
	bool hasColon = false;

	while (*UTF8String != '\0') {
		if (!OFASCIIIsDigit(*UTF8String) && *UTF8String != ':' &&
		    (*UTF8String < 'a' || *UTF8String > 'f') &&
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333







-
+







{
	return (character != '%' && !_characterIsMember(_characterSet,
	    @selector(characterIsMember:), character));
}
@end

void
of_url_verify_escaped(OFString *string, OFCharacterSet *characterSet)
OFURLVerifyEscaped(OFString *string, OFCharacterSet *characterSet)
{
	void *pool = objc_autoreleasePoolPush();

	characterSet = [[[OFInvertedCharacterSetWithoutPercent alloc]
	    initWithCharacterSet: characterSet] autorelease];

	if ([string indexOfCharacterFromSet: characterSet] != OFNotFound)
458
459
460
461
462
463
464
465

466
467
468
469
470
471
472
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472







-
+







		for (tmp2 = UTF8String; tmp2 < tmp; tmp2++)
			*tmp2 = OFASCIIToLower(*tmp2);

		_URLEncodedScheme = [[OFString alloc]
		    initWithUTF8String: UTF8String
				length: tmp - UTF8String];

		of_url_verify_escaped(_URLEncodedScheme,
		OFURLVerifyEscaped(_URLEncodedScheme,
		    [OFCharacterSet URLSchemeAllowedCharacterSet]);

		UTF8String = tmp + 3;

		if ((tmp = strchr(UTF8String, '/')) != NULL) {
			*tmp = '\0';
			tmp++;
483
484
485
486
487
488
489
490

491
492
493
494
495
496
497

498
499
500
501
502
503
504
483
484
485
486
487
488
489

490
491
492
493
494
495
496

497
498
499
500
501
502
503
504







-
+






-
+







				tmp3++;

				_URLEncodedUser = [[OFString alloc]
				    initWithUTF8String: UTF8String];
				_URLEncodedPassword = [[OFString alloc]
				    initWithUTF8String: tmp3];

				of_url_verify_escaped(_URLEncodedPassword,
				OFURLVerifyEscaped(_URLEncodedPassword,
				    [OFCharacterSet
				    URLPasswordAllowedCharacterSet]);
			} else
				_URLEncodedUser = [[OFString alloc]
				    initWithUTF8String: UTF8String];

			of_url_verify_escaped(_URLEncodedUser,
			OFURLVerifyEscaped(_URLEncodedUser,
			    [OFCharacterSet URLUserAllowedCharacterSet]);

			UTF8String = tmp2;
		}

		if (UTF8String[0] == '[') {
			tmp2 = UTF8String++;
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591

592
593
594
595
596
597
598
599
600
601
602

603
604
605
606
607
608
609
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587
588
589
590

591
592
593
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608
609







-
+









-
+










-
+










-
+







			_port = [[OFNumber alloc] initWithUnsignedShort:
			    portString.unsignedLongLongValue];
		} else
			_URLEncodedHost = [[OFString alloc]
			    initWithUTF8String: UTF8String];

		if (!isIPv6Host)
			of_url_verify_escaped(_URLEncodedHost,
			OFURLVerifyEscaped(_URLEncodedHost,
			    [OFCharacterSet URLHostAllowedCharacterSet]);

		if ((UTF8String = tmp) != NULL) {
			if ((tmp = strchr(UTF8String, '#')) != NULL) {
				*tmp = '\0';

				_URLEncodedFragment = [[OFString alloc]
				    initWithUTF8String: tmp + 1];

				of_url_verify_escaped(_URLEncodedFragment,
				OFURLVerifyEscaped(_URLEncodedFragment,
				    [OFCharacterSet
				    URLFragmentAllowedCharacterSet]);
			}

			if ((tmp = strchr(UTF8String, '?')) != NULL) {
				*tmp = '\0';

				_URLEncodedQuery = [[OFString alloc]
				    initWithUTF8String: tmp + 1];

				of_url_verify_escaped(_URLEncodedQuery,
				OFURLVerifyEscaped(_URLEncodedQuery,
				    [OFCharacterSet
				    URLQueryAllowedCharacterSet]);
			}

			UTF8String--;
			*UTF8String = '/';

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

			of_url_verify_escaped(_URLEncodedPath,
			OFURLVerifyEscaped(_URLEncodedPath,
			    [OFCharacterSet URLPathAllowedCharacterSet]);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
641
642
643
644
645
646
647

648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
664







-
+








-
+







		UTF8String = UTF8String2;

		if ((tmp = strchr(UTF8String, '#')) != NULL) {
			*tmp = '\0';
			_URLEncodedFragment = [[OFString alloc]
			    initWithUTF8String: tmp + 1];

			of_url_verify_escaped(_URLEncodedFragment,
			OFURLVerifyEscaped(_URLEncodedFragment,
			    [OFCharacterSet URLFragmentAllowedCharacterSet]);
		}

		if ((tmp = strchr(UTF8String, '?')) != NULL) {
			*tmp = '\0';
			_URLEncodedQuery = [[OFString alloc]
			    initWithUTF8String: tmp + 1];

			of_url_verify_escaped(_URLEncodedQuery,
			OFURLVerifyEscaped(_URLEncodedQuery,
			    [OFCharacterSet URLQueryAllowedCharacterSet]);
		}

		if (*UTF8String == '/')
			_URLEncodedPath = [[OFString alloc]
			    initWithUTF8String: UTF8String];
		else {
690
691
692
693
694
695
696
697

698
699
700
701
702
703
704
690
691
692
693
694
695
696

697
698
699
700
701
702
703
704







-
+







						    withString: relativePath];
				[path makeImmutable];

				_URLEncodedPath = [path copy];
			}
		}

		of_url_verify_escaped(_URLEncodedPath,
		OFURLVerifyEscaped(_URLEncodedPath,
		    [OFCharacterSet URLPathAllowedCharacterSet]);

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	} @finally {
876
877
878
879
880
881
882
883

884
885
886
887
888
889
890
876
877
878
879
880
881
882

883
884
885
886
887
888
889
890







-
+







- (OFString *)host
{
	if ([_URLEncodedHost hasPrefix: @"["] &&
	    [_URLEncodedHost hasSuffix: @"]"]) {
		OFString *host = [_URLEncodedHost substringWithRange:
		    OFRangeMake(1, _URLEncodedHost.length - 2)];

		if (!of_url_is_ipv6_host(host))
		if (!OFURLIsIPv6Host(host))
			@throw [OFInvalidArgumentException exception];

		return host;
	}

	return _URLEncodedHost.stringByURLDecoding;
}

Modified src/OFUTF8String.h from [bd916580b9] to [7a3b643b9d].

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
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







-
+








-
+






-
+
-
-
+





	/*
	 * A pointer to the actual data.
	 *
	 * Since constant strings don't have `_storage`, they have to allocate
	 * it on the first access. Strings created at runtime just set the
	 * pointer to `&_storage`.
	 */
	struct of_string_utf8_ivars {
	struct OFUTF8StringIvars {
		char          *cString;
		size_t        cStringLength;
		bool          isUTF8;
		size_t        length;
		bool          hashed;
		unsigned long hash;
		bool          freeWhenDone;
	} *restrict _s;
	struct of_string_utf8_ivars _storage;
	struct OFUTF8StringIvars _storage;
}
@end

#ifdef __cplusplus
extern "C" {
#endif
extern int of_string_utf8_check(const char *, size_t, size_t *);
extern int OFUTF8StringCheck(const char *, size_t, size_t *);
extern size_t of_string_utf8_get_index(const char *, size_t);
extern size_t of_string_utf8_get_position(const char *, size_t, size_t);
extern size_t OFUTF8StringIndexToPosition(const char *, size_t, size_t);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFUTF8String.m from [3080670bc7] to [d6113071ec].

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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#import "OFInvalidEncodingException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

#import "unicode.h"

extern const OFChar16 of_iso_8859_2_table[];
extern const size_t of_iso_8859_2_table_offset;
extern const OFChar16 of_iso_8859_3_table[];
extern const size_t of_iso_8859_3_table_offset;
extern const OFChar16 of_iso_8859_15_table[];
extern const size_t of_iso_8859_15_table_offset;
extern const OFChar16 of_windows_1251_table[];
extern const size_t of_windows_1251_table_offset;
extern const OFChar16 of_windows_1252_table[];
extern const size_t of_windows_1252_table_offset;
extern const OFChar16 of_codepage_437_table[];
extern const size_t of_codepage_437_table_offset;
extern const OFChar16 of_codepage_850_table[];
extern const size_t of_codepage_850_table_offset;
extern const OFChar16 of_codepage_858_table[];
extern const size_t of_codepage_858_table_offset;
extern const OFChar16 of_mac_roman_table[];
extern const size_t of_mac_roman_table_offset;
extern const OFChar16 of_koi8_r_table[];
extern const size_t of_koi8_r_table_offset;
extern const OFChar16 of_koi8_u_table[];
extern const size_t of_koi8_u_table_offset;
extern const OFChar16 OFISO8859_2Table[];
extern const size_t OFISO8859_2TableOffset;
extern const OFChar16 OFISO8859_3Table[];
extern const size_t OFISO8859_3TableOffset;
extern const OFChar16 OFISO8859_15Table[];
extern const size_t OFISO8859_15TableOffset;
extern const OFChar16 OFWindows1251Table[];
extern const size_t OFWindows1251TableOffset;
extern const OFChar16 OFWindows1252Table[];
extern const size_t OFWindows1252TableOffset;
extern const OFChar16 OFCodepage437Table[];
extern const size_t OFCodepage437TableOffset;
extern const OFChar16 OFCodepage850Table[];
extern const size_t OFCodepage850TableOffset;
extern const OFChar16 OFCodepage858Table[];
extern const size_t OFCodepage858TableOffset;
extern const OFChar16 OFMacRomanTable[];
extern const size_t OFMacRomanTableOffset;
extern const OFChar16 OFKOI8RTable[];
extern const size_t OFKOI8RTableOffset;
extern const OFChar16 OFKOI8UTable[];
extern const size_t OFKOI8UTableOffset;

static inline int
memcasecmp(const char *first, const char *second, size_t length)
{
	for (size_t i = 0; i < length; i++) {
		unsigned char f = first[i];
		unsigned char s = second[i];
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92







-
+







			return OFOrderedAscending;
	}

	return OFOrderedSame;
}

int
of_string_utf8_check(const char *UTF8String, size_t UTF8Length, size_t *length)
OFUTF8StringCheck(const char *UTF8String, size_t UTF8Length, size_t *length)
{
	size_t tmpLength = UTF8Length;
	int isUTF8 = 0;

	for (size_t i = 0; i < UTF8Length; i++) {
		/* No sign of UTF-8 here */
		if OF_LIKELY (!(UTF8String[i] & 0x80))
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
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







-
+











-
+







	if (length != NULL)
		*length = tmpLength;

	return isUTF8;
}

size_t
of_string_utf8_get_index(const char *string, size_t position)
positionToIndex(const char *string, size_t position)
{
	size_t idx = position;

	for (size_t i = 0; i < position; i++)
		if OF_UNLIKELY ((string[i] & 0xC0) == 0x80)
			idx--;

	return idx;
}

size_t
of_string_utf8_get_position(const char *string, size_t idx, size_t length)
OFUTF8StringIndexToPosition(const char *string, size_t idx, size_t length)
{
	for (size_t i = 0; i <= idx; i++)
		if OF_UNLIKELY ((string[i] & 0xC0) == 0x80)
			if (++idx > length)
				@throw [OFInvalidFormatException exception];

	return idx;
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217







-
+







		}

		_s = &_storage;

		_s->cString = storage;
		_s->cStringLength = UTF8StringLength;

		switch (of_string_utf8_check(UTF8String, UTF8StringLength,
		switch (OFUTF8StringCheck(UTF8String, UTF8StringLength,
		    &_s->length)) {
		case 1:
			_s->isUTF8 = true;
			break;
		case -1:
			@throw [OFInvalidEncodingException exception];
		}
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261







-
+








		_s->cString = OFAllocMemory(cStringLength + 1, 1);
		_s->cStringLength = cStringLength;
		_s->freeWhenDone = true;

		if (encoding == OFStringEncodingUTF8 ||
		    encoding == OFStringEncodingASCII) {
			switch (of_string_utf8_check(cString, cStringLength,
			switch (OFUTF8StringCheck(cString, cStringLength,
			    &_s->length)) {
			case 1:
				if (encoding == OFStringEncodingASCII)
					@throw [OFInvalidEncodingException
					    exception];

				_s->isUTF8 = true;
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295







-
+








				if (!(cString[i] & 0x80)) {
					_s->cString[j++] = cString[i];
					continue;
				}

				_s->isUTF8 = true;
				bytes = of_string_utf8_encode(
				bytes = OFUTF8StringEncode(
				    (uint8_t)cString[i], buffer);

				if (bytes == 0)
					@throw [OFInvalidEncodingException
					    exception];

				_s->cStringLength += bytes - 1;
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

337
338
339

340
341
342

343
344
345

346
347
348
349
350
351
352
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
337
338

339
340
341

342
343
344

345
346
347
348
349
350
351
352







-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+







			return self;
		}

		switch (encoding) {
#define CASE(encoding, var)				\
		case encoding:				\
			table = var;			\
			tableOffset = var##_offset;	\
			tableOffset = var##Offset;	\
			break;
#ifdef HAVE_ISO_8859_2
		CASE(OFStringEncodingISO8859_2, of_iso_8859_2_table)
		CASE(OFStringEncodingISO8859_2, OFISO8859_2Table)
#endif
#ifdef HAVE_ISO_8859_3
		CASE(OFStringEncodingISO8859_3, of_iso_8859_3_table)
		CASE(OFStringEncodingISO8859_3, OFISO8859_3Table)
#endif
#ifdef HAVE_ISO_8859_15
		CASE(OFStringEncodingISO8859_15, of_iso_8859_15_table)
		CASE(OFStringEncodingISO8859_15, OFISO8859_15Table)
#endif
#ifdef HAVE_WINDOWS_1251
		CASE(OFStringEncodingWindows1251, of_windows_1251_table)
		CASE(OFStringEncodingWindows1251, OFWindows1251Table)
#endif
#ifdef HAVE_WINDOWS_1252
		CASE(OFStringEncodingWindows1252, of_windows_1252_table)
		CASE(OFStringEncodingWindows1252, OFWindows1252Table)
#endif
#ifdef HAVE_CODEPAGE_437
		CASE(OFStringEncodingCodepage437, of_codepage_437_table)
		CASE(OFStringEncodingCodepage437, OFCodepage437Table)
#endif
#ifdef HAVE_CODEPAGE_850
		CASE(OFStringEncodingCodepage850, of_codepage_850_table)
		CASE(OFStringEncodingCodepage850, OFCodepage850Table)
#endif
#ifdef HAVE_CODEPAGE_858
		CASE(OFStringEncodingCodepage858, of_codepage_858_table)
		CASE(OFStringEncodingCodepage858, OFCodepage858Table)
#endif
#ifdef HAVE_MAC_ROMAN
		CASE(OFStringEncodingMacRoman, of_mac_roman_table)
		CASE(OFStringEncodingMacRoman, OFMacRomanTable)
#endif
#ifdef HAVE_KOI8_R
		CASE(OFStringEncodingKOI8R, of_koi8_r_table)
		CASE(OFStringEncodingKOI8R, OFKOI8RTable)
#endif
#ifdef HAVE_KOI8_U
		CASE(OFStringEncodingKOI8U, of_koi8_u_table)
		CASE(OFStringEncodingKOI8U, OFKOI8UTable)
#endif
#undef CASE
		default:
			@throw [OFInvalidEncodingException exception];
		}

		j = 0;
363
364
365
366
367
368
369
370

371
372
373
374
375
376
377
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377







-
+








			unichar = table[character - tableOffset];

			if (unichar == 0xFFFF)
				@throw [OFInvalidEncodingException exception];

			_s->isUTF8 = true;
			byteLength = of_string_utf8_encode(unichar, buffer);
			byteLength = OFUTF8StringEncode(unichar, buffer);

			if (byteLength == 0)
				@throw [OFInvalidEncodingException exception];

			_s->cStringLength += byteLength - 1;
			_s->cString = OFResizeMemory(_s->cString,
			    _s->cStringLength + 1, 1);
409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423







-
+








		if (UTF8StringLength >= 3 &&
		    memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) {
			UTF8String += 3;
			UTF8StringLength -= 3;
		}

		switch (of_string_utf8_check(UTF8String, UTF8StringLength,
		switch (OFUTF8StringCheck(UTF8String, UTF8StringLength,
		    &_s->length)) {
		case 1:
			_s->isUTF8 = true;
			break;
		case -1:
			@throw [OFInvalidEncodingException exception];
		}
473
474
475
476
477
478
479
480

481
482
483
484
485
486
487
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487







-
+








		_s->cString = OFAllocMemory((length * 4) + 1, 1);
		_s->length = length;
		_s->freeWhenDone = true;

		j = 0;
		for (size_t i = 0; i < length; i++) {
			size_t len = of_string_utf8_encode(characters[i],
			size_t len = OFUTF8StringEncode(characters[i],
			    _s->cString + j);

			if (len == 0)
				@throw [OFInvalidEncodingException exception];

			if (len > 1)
				_s->isUTF8 = true;
559
560
561
562
563
564
565
566

567
568
569
570
571
572
573
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573







-
+







				character = (((character & 0x3FF) << 10) |
				    (nextCharacter & 0x3FF)) + 0x10000;

				i++;
				_s->length--;
			}

			len = of_string_utf8_encode(character, _s->cString + j);
			len = OFUTF8StringEncode(character, _s->cString + j);

			if (len == 0)
				@throw [OFInvalidEncodingException exception];

			if (len > 1)
				_s->isUTF8 = true;

615
616
617
618
619
620
621
622

623
624
625
626
627
628
629
615
616
617
618
619
620
621

622
623
624
625
626
627
628
629







-
+







		_s->cString = OFAllocMemory((length * 4) + 1, 1);
		_s->length = length;
		_s->freeWhenDone = true;

		j = 0;
		for (size_t i = 0; i < length; i++) {
			char buffer[4];
			size_t len = of_string_utf8_encode((swap
			size_t len = OFUTF8StringEncode((swap
			    ? OFByteSwap32(characters[i])
			    : characters[i]),
			    buffer);

			switch (len) {
			case 1:
				_s->cString[j++] = buffer[0];
675
676
677
678
679
680
681
682

683
684
685
686
687
688
689
675
676
677
678
679
680
681

682
683
684
685
686
687
688
689







-
+







		if ((cStringLength = OFVASPrintF(&tmp, format.UTF8String,
		    arguments)) == -1)
			@throw [OFInvalidFormatException exception];

		_s->cStringLength = cStringLength;

		@try {
			switch (of_string_utf8_check(tmp, cStringLength,
			switch (OFUTF8StringCheck(tmp, cStringLength,
			    &_s->length)) {
			case 1:
				_s->isUTF8 = true;
				break;
			case -1:
				@throw [OFInvalidEncodingException exception];
			}
869
870
871
872
873
874
875
876

877
878

879
880
881
882
883
884

885
886

887
888
889
890
891
892

893
894

895
896
897
898
899
900
901
869
870
871
872
873
874
875

876
877

878
879
880
881
882
883

884
885

886
887
888
889
890
891

892
893

894
895
896
897
898
899
900
901







-
+

-
+





-
+

-
+





-
+

-
+








	i = j = 0;

	while (i < _s->cStringLength && j < otherCStringLength) {
		OFUnichar c1, c2;
		ssize_t l1, l2;

		l1 = of_string_utf8_decode(_s->cString + i,
		l1 = OFUTF8StringDecode(_s->cString + i,
		    _s->cStringLength - i, &c1);
		l2 = of_string_utf8_decode(otherCString + j,
		l2 = OFUTF8StringDecode(otherCString + j,
		    otherCStringLength - j, &c2);

		if (l1 <= 0 || l2 <= 0 || c1 > 0x10FFFF || c2 > 0x10FFFF)
			@throw [OFInvalidEncodingException exception];

		if (c1 >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) {
		if (c1 >> 8 < OFUnicodeCaseFoldingTableSize) {
			OFUnichar tc =
			    of_unicode_casefolding_table[c1 >> 8][c1 & 0xFF];
			    OFUnicodeCaseFoldingTable[c1 >> 8][c1 & 0xFF];

			if (tc)
				c1 = tc;
		}

		if (c2 >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) {
		if (c2 >> 8 < OFUnicodeCaseFoldingTableSize) {
			OFUnichar tc =
			    of_unicode_casefolding_table[c2 >> 8][c2 & 0xFF];
			    OFUnicodeCaseFoldingTable[c2 >> 8][c2 & 0xFF];

			if (tc)
				c2 = tc;
		}

		if (c1 > c2)
			return OFOrderedDescending;
924
925
926
927
928
929
930
931

932
933
934
935
936
937
938
924
925
926
927
928
929
930

931
932
933
934
935
936
937
938







-
+








	OFHashInit(&hash);

	for (size_t i = 0; i < _s->cStringLength; i++) {
		OFUnichar c;
		ssize_t length;

		if ((length = of_string_utf8_decode(_s->cString + i,
		if ((length = OFUTF8StringDecode(_s->cString + i,
		    _s->cStringLength - i, &c)) <= 0)
			@throw [OFInvalidEncodingException exception];

		OFHashAdd(&hash, (c & 0xFF0000) >> 16);
		OFHashAdd(&hash, (c & 0x00FF00) >> 8);
		OFHashAdd(&hash, c & 0x0000FF);

953
954
955
956
957
958
959
960

961
962
963


964
965
966
967
968
969
970
953
954
955
956
957
958
959

960
961


962
963
964
965
966
967
968
969
970







-
+

-
-
+
+








	if (idx >= _s->length)
		@throw [OFOutOfRangeException exception];

	if (!_s->isUTF8)
		return _s->cString[idx];

	idx = of_string_utf8_get_position(_s->cString, idx, _s->cStringLength);
	idx = OFUTF8StringIndexToPosition(_s->cString, idx, _s->cStringLength);

	if (of_string_utf8_decode(_s->cString + idx,
	    _s->cStringLength - idx, &character) <= 0)
	if (OFUTF8StringDecode(_s->cString + idx, _s->cStringLength - idx,
	    &character) <= 0)
		@throw [OFInvalidEncodingException exception];

	return character;
}

- (void)getCharacters: (OFUnichar *)buffer inRange: (OFRange)range
{
991
992
993
994
995
996
997
998

999
1000

1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018

1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033

1034
1035
1036
1037
1038
1039
1040
991
992
993
994
995
996
997

998
999

1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017

1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
1040







-
+

-
+

















-
+














-
+







	size_t rangeLocation, rangeLength;

	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _s->length)
		@throw [OFOutOfRangeException exception];

	if (_s->isUTF8) {
		rangeLocation = of_string_utf8_get_position(
		rangeLocation = OFUTF8StringIndexToPosition(
		    _s->cString, range.location, _s->cStringLength);
		rangeLength = of_string_utf8_get_position(
		rangeLength = OFUTF8StringIndexToPosition(
		    _s->cString + rangeLocation, range.length,
		    _s->cStringLength - rangeLocation);
	} else {
		rangeLocation = range.location;
		rangeLength = range.length;
	}

	if (cStringLength == 0)
		return OFRangeMake(0, 0);

	if (cStringLength > rangeLength)
		return OFRangeMake(OFNotFound, 0);

	if (options & OFStringSearchBackwards) {
		for (size_t i = rangeLength - cStringLength;; i--) {
			if (memcmp(_s->cString + rangeLocation + i, cString,
			    cStringLength) == 0) {
				range.location += of_string_utf8_get_index(
				range.location += positionToIndex(
				    _s->cString + rangeLocation, i);
				range.length = string.length;

				return range;
			}

			/* Did not match and we're at the last char */
			if (i == 0)
				return OFRangeMake(OFNotFound, 0);
		}
	} else {
		for (size_t i = 0; i <= rangeLength - cStringLength; i++) {
			if (memcmp(_s->cString + rangeLocation + i, cString,
			    cStringLength) == 0) {
				range.location += of_string_utf8_get_index(
				range.location += positionToIndex(
				    _s->cString + rangeLocation, i);
				range.length = string.length;

				return range;
			}
		}
	}
1065
1066
1067
1068
1069
1070
1071
1072

1073
1074

1075
1076
1077
1078
1079
1080
1081
1065
1066
1067
1068
1069
1070
1071

1072
1073

1074
1075
1076
1077
1078
1079
1080
1081







-
+

-
+







	size_t start = range.location;
	size_t end = range.location + range.length;

	if (range.length > SIZE_MAX - range.location || end > _s->length)
		@throw [OFOutOfRangeException exception];

	if (_s->isUTF8) {
		start = of_string_utf8_get_position(_s->cString, start,
		start = OFUTF8StringIndexToPosition(_s->cString, start,
		    _s->cStringLength);
		end = of_string_utf8_get_position(_s->cString, end,
		end = OFUTF8StringIndexToPosition(_s->cString, end,
		    _s->cStringLength);
	}

	return [OFString stringWithUTF8String: _s->cString + start
				       length: end - start];
}

1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
1172







-
+







	OFUnichar *buffer = OFAllocMemory(_s->length, sizeof(OFUnichar));
	size_t i = 0, j = 0;

	while (i < _s->cStringLength) {
		OFUnichar c;
		ssize_t cLen;

		cLen = of_string_utf8_decode(_s->cString + i,
		cLen = OFUTF8StringDecode(_s->cString + i,
		    _s->cStringLength - i, &c);

		if (cLen <= 0 || c > 0x10FFFF) {
			OFFreeMemory(buffer);
			@throw [OFInvalidEncodingException exception];
		}

1185
1186
1187
1188
1189
1190
1191
1192

1193
1194
1195
1196
1197
1198
1199
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198
1199







-
+







	OFChar32 *buffer = OFAllocMemory(_s->length + 1, sizeof(OFChar32));
	size_t i = 0, j = 0;

	while (i < _s->cStringLength) {
		OFChar32 c;
		ssize_t cLen;

		cLen = of_string_utf8_decode(_s->cString + i,
		cLen = OFUTF8StringDecode(_s->cString + i,
		    _s->cStringLength - i, &c);

		if (cLen <= 0 || c > 0x10FFFF) {
			OFFreeMemory(buffer);
			@throw [OFInvalidEncodingException exception];
		}

Modified src/OFValue.m from [cf82e8bfac] to [2892e2bc96].

93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107







-
+







		return false;

	objCType = self.objCType;

	if (strcmp([object objCType], objCType) != 0)
		return false;

	size = of_sizeof_type_encoding(objCType);
	size = OFSizeOfTypeEncoding(objCType);

	value = OFAllocMemory(1, size);
	@try {
		otherValue = OFAllocMemory(1, size);
	} @catch (id e) {
		OFFreeMemory(value);
		@throw e;
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131







-
+







	}

	return ret;
}

- (unsigned long)hash
{
	size_t size = of_sizeof_type_encoding(self.objCType);
	size_t size = OFSizeOfTypeEncoding(self.objCType);
	unsigned char *value;
	unsigned long hash;

	value = OFAllocMemory(1, size);
	@try {
		[self getValue: value size: size];

199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213







-
+







	return ret;
}

- (OFString *)description
{
	OFMutableString *ret =
	    [OFMutableString stringWithString: @"<OFValue: "];
	size_t size = of_sizeof_type_encoding(self.objCType);
	size_t size = OFSizeOfTypeEncoding(self.objCType);
	unsigned char *value;

	value = OFAllocMemory(1, size);
	@try {
		[self getValue: value size: size];

		for (size_t i = 0; i < size; i++) {

Modified src/OFWin32ConsoleStdIOStream.m from [117f6c572a] to [3aed091d75].

22
23
24
25
26
27
28
29

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

29
30
31
32
33
34
35
36







-
+







 * For example, on Windows XP, when using Windows XP's console, changing the
 * codepage to UTF-8 mostly breaks write() and completely breaks read():
 * write() suddenly returns the number of characters - instead of bytes -
 * written and read() just returns 0 as soon as a Unicode character is being
 * read.
 *
 * Therefore, instead of just using the UTF-8 codepage, this captures all reads
 * and writes to of_std{in,out,err} on the low level, interprets the buffer as
 * and writes to OFStd{In,Out,Err} on the low level, interprets the buffer as
 * UTF-8 and converts to / from UTF-16 to use ReadConsoleW() / WriteConsoleW().
 * Doing so is safe, as the console only supports text anyway and thus it does
 * not matter if binary gets garbled by the conversion (e.g. because invalid
 * UTF-8 gets converted to U+FFFD).
 *
 * In order to not do this when redirecting input / output to a file (as the
 * file would then be read / written in the wrong encoding and break reading /
84
85
86
87
88
89
90
91

92
93
94

95
96
97

98
99
100
101
102
103
104
84
85
86
87
88
89
90

91
92
93

94
95
96

97
98
99
100
101
102
103
104







-
+


-
+


-
+







{
	int fd;

	if (self != [OFWin32ConsoleStdIOStream class])
		return;

	if ((fd = _fileno(stdin)) >= 0)
		of_stdin = [[OFWin32ConsoleStdIOStream alloc]
		OFStdIn = [[OFWin32ConsoleStdIOStream alloc]
		    of_initWithFileDescriptor: fd];
	if ((fd = _fileno(stdout)) >= 0)
		of_stdout = [[OFWin32ConsoleStdIOStream alloc]
		OFStdOut = [[OFWin32ConsoleStdIOStream alloc]
		    of_initWithFileDescriptor: fd];
	if ((fd = _fileno(stderr)) >= 0)
		of_stderr = [[OFWin32ConsoleStdIOStream alloc]
		OFStdErr = [[OFWin32ConsoleStdIOStream alloc]
		    of_initWithFileDescriptor: fd];
}

- (instancetype)of_initWithFileDescriptor: (int)fd
{
	self = [super of_initWithFileDescriptor: fd];

175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189







-
+







		if (UTF16Len > 0 && _incompleteUTF16Surrogate != 0) {
			OFUnichar c =
			    (((_incompleteUTF16Surrogate & 0x3FF) << 10) |
			    (UTF16[0] & 0x3FF)) + 0x10000;
			char UTF8[4];
			size_t UTF8Len;

			if ((UTF8Len = of_string_utf8_encode(c, UTF8)) == 0)
			if ((UTF8Len = OFUTF8StringEncode(c, UTF8)) == 0)
				@throw [OFInvalidEncodingException exception];

			if (UTF8Len <= length) {
				memcpy(buffer, UTF8, UTF8Len);
				j += UTF8Len;
			} else {
				if (rest == nil)
232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246







-
+








				c = (((c & 0x3FF) << 10) | (next & 0x3FF)) +
				    0x10000;

				i++;
			}

			if ((UTF8Len = of_string_utf8_encode(c, UTF8)) == 0)
			if ((UTF8Len = OFUTF8StringEncode(c, UTF8)) == 0)
				@throw [OFInvalidEncodingException exception];

			if (j + UTF8Len <= length) {
				memcpy(buffer + j, UTF8, UTF8Len);
				j += UTF8Len;
			} else {
				if (rest == nil)
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
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







-
+















-
+







	if (_incompleteUTF8SurrogateLen > 0) {
		OFUnichar c;
		OFChar16 UTF16[2];
		ssize_t UTF8Len;
		size_t toCopy;
		DWORD UTF16Len, bytesWritten;

		UTF8Len = -of_string_utf8_decode(
		UTF8Len = -OFUTF8StringDecode(
		    _incompleteUTF8Surrogate, _incompleteUTF8SurrogateLen, &c);

		OFEnsure(UTF8Len > 0);

		toCopy = UTF8Len - _incompleteUTF8SurrogateLen;
		if (toCopy > length)
			toCopy = length;

		memcpy(_incompleteUTF8Surrogate + _incompleteUTF8SurrogateLen,
		    buffer, toCopy);
		_incompleteUTF8SurrogateLen += toCopy;

		if (_incompleteUTF8SurrogateLen < (size_t)UTF8Len)
			return 0;

		UTF8Len = of_string_utf8_decode(
		UTF8Len = OFUTF8StringDecode(
		    _incompleteUTF8Surrogate, _incompleteUTF8SurrogateLen, &c);

		if (UTF8Len <= 0 || c > 0x10FFFF) {
			assert(UTF8Len == 0 || UTF8Len < -4);

			UTF16[0] = 0xFFFD;
			UTF16Len = 1;
361
362
363
364
365
366
367
368

369
370
371
372
373
374
375
361
362
363
364
365
366
367

368
369
370
371
372
373
374
375







-
+







	@try {
		DWORD bytesWritten;

		while (i < length) {
			OFUnichar c;
			ssize_t UTF8Len;

			UTF8Len = of_string_utf8_decode(buffer + i, length - i,
			UTF8Len = OFUTF8StringDecode(buffer + i, length - i,
			    &c);

			if (UTF8Len < 0 && UTF8Len >= -4) {
				OFEnsure(length - i < 4);

				memcpy(_incompleteUTF8Surrogate, buffer + i,
				    length - i);

Modified src/OFZIPArchive.h from [12eebcf96b] to [35e140687b].

167
168
169
170
171
172
173
174











175
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186








+
+
+
+
+
+
+
+
+
+
+

- (OFStream *)streamForWritingEntry: (OFZIPArchiveEntry *)entry;

/**
 * @brief Closes the OFZIPArchive.
 */
- (void)close;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t OFZIPArchiveReadField32(const uint8_t *_Nonnull *_Nonnull,
    uint16_t *_Nonnull);
extern uint64_t OFZIPArchiveReadField64(const uint8_t *_Nonnull *_Nonnull,
    uint16_t *_Nonnull);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFZIPArchiveEntry.m from [4408bc6ea7] to [a82b90cc04].

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



29
30
31
32
33
34
35







-
-
-







#import "OFStream.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"

extern uint32_t OFZIPArchiveReadField32(const uint8_t **, uint16_t *);
extern uint64_t OFZIPArchiveReadField64(const uint8_t **, uint16_t *);

OFString *
OFZIPArchiveEntryVersionToString(uint16_t version)
{
	const char *attrCompat = NULL;

	switch (version >> 8) {
	case OFZIPArchiveEntryAttributeCompatibilityMSDOS:

Modified src/encodings/codepage-437.m from [e4e7c7d238] to [1ff55c3103].

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
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







-
+

















-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_codepage_437_table[] = {
const OFChar16 OFCodepage437Table[] = {
	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
	0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
	0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
	0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
	0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
	0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
	0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
const size_t of_codepage_437_table_offset =
    256 - (sizeof(of_codepage_437_table) / sizeof(*of_codepage_437_table));
const size_t OFCodepage437TableOffset =
    256 - (sizeof(OFCodepage437Table) / sizeof(*OFCodepage437Table));

static const unsigned char page0[] = {
	0xFF, 0xAD, 0x9B, 0x9C, 0x00, 0x9D, 0x00, 0x00,
	0x00, 0x00, 0xA6, 0xAE, 0xAA, 0x00, 0x00, 0x00,
	0xF8, 0xF1, 0xFD, 0x00, 0x00, 0xE6, 0x00, 0xFA,
	0x00, 0x00, 0xA7, 0xAF, 0xAC, 0xAB, 0x00, 0xA8,
	0x00, 0x00, 0x00, 0x00, 0x8E, 0x8F, 0x92, 0x80,
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139







-
+







	0xDE, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xFE
};
static const uint8_t page25Start = 0x00;

bool
of_unicode_to_codepage_437(const OFUnichar *input, unsigned char *output,
OFUnicodeToCodepage437(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/codepage-850.m from [749e880312] to [8a999f8dc5].

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
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







-
+

















-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_codepage_850_table[] = {
const OFChar16 OFCodepage850Table[] = {
	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
	0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
	0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
	0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
	0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
	0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
	0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
	0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
	0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
const size_t of_codepage_850_table_offset =
    256 - (sizeof(of_codepage_850_table) / sizeof(*of_codepage_850_table));
const size_t OFCodepage850TableOffset =
    256 - (sizeof(OFCodepage850Table) / sizeof(*OFCodepage850Table));


static const unsigned char page0[] = {
	0xFF, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0xDD, 0xF5,
	0xF9, 0xB8, 0xA6, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE,
	0xF8, 0xF1, 0xFD, 0xFC, 0xEF, 0xE6, 0xF4, 0xFA,
	0xF7, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8,
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115







-
+







	0x00, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xFE
};
static const uint8_t page25Start = 0x00;

bool
of_unicode_to_codepage_850(const OFUnichar *input, unsigned char *output,
OFUnicodeToCodepage850(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/codepage-858.m from [713f34e1a5] to [eb400d443e].

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
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







-
+

















-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_codepage_858_table[] = {
const OFChar16 OFCodepage858Table[] = {
	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
	0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
	0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
	0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
	0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
	0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
	0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
	0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
	0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
const size_t of_codepage_858_table_offset =
    256 - (sizeof(of_codepage_858_table) / sizeof(*of_codepage_858_table));
const size_t OFCodepage858TableOffset =
    256 - (sizeof(OFCodepage858Table) / sizeof(*OFCodepage858Table));


static const unsigned char page0[] = {
	0xFF, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0xDD, 0xF5,
	0xF9, 0xB8, 0xA6, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE,
	0xF8, 0xF1, 0xFD, 0xFC, 0xEF, 0xE6, 0xF4, 0xFA,
	0xF7, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8,
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121







-
+







	0x00, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xFE
};
static const uint8_t page25Start = 0x00;

bool
of_unicode_to_codepage_858(const OFUnichar *input, unsigned char *output,
OFUnicodeToCodepage858(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/iso-8859-15.m from [4e7f7697f6] to [22626a7166].

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
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







-
+













-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_iso_8859_15_table[] = {
const OFChar16 OFISO8859_15Table[] = {
	0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7,
	0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7,
	0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF,
	0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
	0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
	0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
	0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
	0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
	0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
	0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};
const size_t of_iso_8859_15_table_offset =
    256 - (sizeof(of_iso_8859_15_table) / sizeof(*of_iso_8859_15_table));
const size_t OFISO8859_15TableOffset =
    256 - (sizeof(OFISO8859_15Table) / sizeof(*OFISO8859_15Table));

static const unsigned char page0[] = {
	0x00, 0xA5, 0x00, 0xA7, 0x00, 0xA9, 0xAA, 0xAB,
	0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
	0x00, 0xB5, 0xB6, 0xB7, 0x00, 0xB9, 0xBA, 0xBB,
	0x00, 0x00, 0x00
};
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70







-
+








static const unsigned char page20[] = {
	0xA4
};
static const uint8_t page20Start = 0xAC;

bool
of_unicode_to_iso_8859_15(const OFUnichar *input, unsigned char *output,
OFUnicodeToISO8859_15(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/iso-8859-2.m from [9e8609b7f9] to [e41926d484].

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
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







-
+













-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_iso_8859_2_table[] = {
const OFChar16 OFISO8859_2Table[] = {
	0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
	0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
	0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
	0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
	0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
	0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
	0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
	0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
	0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
	0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
	0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
	0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
};
const size_t of_iso_8859_2_table_offset =
    256 - (sizeof(of_iso_8859_2_table) / sizeof(*of_iso_8859_2_table));
const size_t OFISO8859_2TableOffset =
    256 - (sizeof(OFISO8859_2Table) / sizeof(*OFISO8859_2Table));

static const unsigned char page0[] = {
	0xA0, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, 0xA7,
	0xA8, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00,
	0xB0, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00,
	0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xC1, 0xC2, 0x00, 0xC4, 0x00, 0x00, 0xC7,
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90







-
+







	0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xA2, 0xFF, 0x00, 0xB2, 0x00, 0xBD
};
static const uint8_t page2Start = 0xC7;

bool
of_unicode_to_iso_8859_2(const OFUnichar *input, unsigned char *output,
OFUnicodeToISO8859_2(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/iso-8859-3.m from [0df871c6b9] to [5ad1bdc273].

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
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







-
+













-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_iso_8859_3_table[] = {
const OFChar16 OFISO8859_3Table[] = {
	0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0xFFFF, 0x0124, 0x00A7,
	0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0xFFFF, 0x017B,
	0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7,
	0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0xFFFF, 0x017C,
	0x00C0, 0x00C1, 0x00C2, 0xFFFF, 0x00C4, 0x010A, 0x0108, 0x00C7,
	0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
	0xFFFF, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7,
	0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
	0x00E0, 0x00E1, 0x00E2, 0xFFFF, 0x00E4, 0x010B, 0x0109, 0x00E7,
	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
	0xFFFF, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7,
	0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9
};
const size_t of_iso_8859_3_table_offset =
    256 - (sizeof(of_iso_8859_3_table) / sizeof(*of_iso_8859_3_table));
const size_t OFISO8859_3TableOffset =
    256 - (sizeof(OFISO8859_3Table) / sizeof(*OFISO8859_3Table));

static const unsigned char page0[] = {
	0xA0, 0x00, 0x00, 0xA3, 0xA4, 0x00, 0x00, 0xA7,
	0xA8, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00,
	0xB0, 0x00, 0xB2, 0xB3, 0xB4, 0xB5, 0x00, 0xB7,
	0xB8, 0x00, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00,
	0xC0, 0xC1, 0xC2, 0x00, 0xC4, 0x00, 0x00, 0xC7,
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87







-
+








static const unsigned char page2[] = {
	0xA2, 0xFF
};
static const uint8_t page2Start = 0xD8;

bool
of_unicode_to_iso_8859_3(const OFUnichar *input, unsigned char *output,
OFUnicodeToISO8859_3(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/koi8-r.m from [e0fb41e40c] to [bf43e53144].

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
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







-
+

















-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_koi8_r_table[] = {
const OFChar16 OFKOI8RTable[] = {
	0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
	0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
	0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
	0x2264,	0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
	0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
	0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
	0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
	0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
	0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
	0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
	0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
	0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
	0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
	0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
	0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
	0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
};
const size_t of_koi8_r_table_offset =
    256 - (sizeof(of_koi8_r_table) / sizeof(*of_koi8_r_table));
const size_t OFKOI8RTableOffset =
    256 - (sizeof(OFKOI8RTable) / sizeof(*OFKOI8RTable));

static const unsigned char page0[] = {
	0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x9C, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x9E,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111
112
113
114
115
116
117
118
119


120
121
122
123
124
125
126
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126







-
-
+
+







	0x8F, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x94
};
static const uint8_t page25Start = 0x00;

bool
of_unicode_to_koi8_r(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
OFUnicodeToKOI8R(const OFUnichar *input, unsigned char *output, size_t length,
    bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/koi8-u.m from [6a1434b3fd] to [71921000c0].

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
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







-
+

















-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_koi8_u_table[] = {
const OFChar16 OFKOI8UTable[] = {
	0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
	0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
	0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
	0x2264,	0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
	0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457,
	0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x0491, 0x255D, 0x255E,
	0x255F, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
	0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x0490, 0x256C, 0x00A9,
	0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
	0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
	0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
	0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
	0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
	0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
	0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
	0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
};
const size_t of_koi8_u_table_offset =
    256 - (sizeof(of_koi8_u_table) / sizeof(*of_koi8_u_table));
const size_t OFKOI8UTableOffset =
    256 - (sizeof(OFKOI8UTable) / sizeof(*OFKOI8UTable));

static const unsigned char page0[] = {
	0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x9C, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x9E,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119
120
121
122
123
124
125
126
127


128
129
130
131
132
133
134
119
120
121
122
123
124
125


126
127
128
129
130
131
132
133
134







-
-
+
+







	0x8F, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x94
};
static const uint8_t page25Start = 0x00;

bool
of_unicode_to_koi8_u(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
OFUnicodeToKOI8U(const OFUnichar *input, unsigned char *output, size_t length,
    bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/mac-roman.m from [c331a2e488] to [3797f74af2].

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
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







-
+

















-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_mac_roman_table[] = {
const OFChar16 OFMacRomanTable[] = {
	0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1,
	0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8,
	0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3,
	0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC,
	0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF,
	0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8,
	0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211,
	0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8,
	0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB,
	0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153,
	0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA,
	0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02,
	0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1,
	0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4,
	0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC,
	0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7
};
const size_t of_mac_roman_table_offset =
    256 - (sizeof(of_mac_roman_table) / sizeof(*of_mac_roman_table));
const size_t OFMacRomanTableOffset =
    256 - (sizeof(OFMacRomanTable) / sizeof(*OFMacRomanTable));

static const unsigned char page0[] = {
	0xCA, 0xC1, 0xA2, 0xA3, 0x00, 0xB4, 0x00, 0xA4,
	0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0x00, 0xA8, 0xF8,
	0xA1, 0xB1, 0x00, 0x00, 0xAB, 0xB5, 0xA6, 0xE1,
	0xFC, 0x00, 0xBC, 0xC8, 0x00, 0x00, 0x00, 0xC0,
	0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82,
145
146
147
148
149
150
151
152

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

152
153
154
155
156
157
158
159







-
+








static const unsigned char pageFB[] = {
	0xDE, 0xDF
};
static const uint8_t pageFBStart = 0x01;

bool
of_unicode_to_mac_roman(const OFUnichar *input, unsigned char *output,
OFUnicodeToMacRoman(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/windows-1251.m from [23d0ff0ab8] to [05f0643067].

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
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







-
+

















-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_windows_1251_table[] = {
const OFChar16 OFWindows1251Table[] = {
	0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
	0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
	0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
	0xFFFF, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
	0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
	0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
	0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
	0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
	0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
	0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
	0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
	0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
	0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
	0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
	0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
	0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
};
const size_t of_windows_1251_table_offset =
    256 - (sizeof(of_windows_1251_table) / sizeof(*of_windows_1251_table));
const size_t OFWindows1251TableOffset =
    256 - (sizeof(OFWindows1251Table) / sizeof(*OFWindows1251Table));

static const unsigned char page0[] = {
	0xA0, 0x00, 0x00, 0x00, 0xA4, 0x00, 0xA6, 0xA7,
	0x00, 0xA9, 0x00, 0xAB, 0xAC, 0xAD, 0xAE, 0x00,
	0xB0, 0xB1, 0x00, 0x00, 0x00, 0xB5, 0xB6, 0xB7,
	0x00, 0x00, 0x00, 0xBB
};
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112







-
+







static const unsigned char page21[] = {
	0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x99
};
static const uint8_t page21Start = 0x16;

bool
of_unicode_to_windows_1251(const OFUnichar *input, unsigned char *output,
OFUnicodeToWindows1251(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/encodings/windows-1252.m from [0483911e0f] to [b4937f91b7].

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
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







-
+

















-
-
+
+








#include "config.h"

#import "OFString.h"

#import "common.h"

const OFChar16 of_windows_1252_table[] = {
const OFChar16 OFWindows1252Table[] = {
	0x20AC, 0xFFFF, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
	0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFF, 0x017D, 0xFFFF,
	0xFFFF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
	0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFF, 0x017E, 0x0178,
	0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
	0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
	0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
	0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
	0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
	0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
	0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
	0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
	0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
	0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};
const size_t of_windows_1252_table_offset =
    256 - (sizeof(of_windows_1252_table) / sizeof(*of_windows_1252_table));
const size_t OFWindows1252TableOffset =
    256 - (sizeof(OFWindows1252Table) / sizeof(*OFWindows1252Table));

static const unsigned char page0[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108







-
+








static const unsigned char page21[] = {
	0x99
};
static const uint8_t page21Start = 0x22;

bool
of_unicode_to_windows_1252(const OFUnichar *input, unsigned char *output,
OFUnicodeToWindows1252(const OFUnichar *input, unsigned char *output,
    size_t length, bool lossy)
{
	for (size_t i = 0; i < length; i++) {
		OFUnichar c = input[i];

		if OF_UNLIKELY (c > 0x7F) {
			uint8_t idx;

Modified src/exceptions/OFAcceptFailedException.m from [2edba3e966] to [f160570582].

53
54
55
56
57
58
59
60

61
62
53
54
55
56
57
58
59

60
61
62







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to accept connection in socket of class %@: %@",
	    [_socket class], of_strerror(_errNo)];
	    [_socket class], OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFBindFailedException.m from [8a08ee6973] to [5d40ea5e4f].

104
105
106
107
108
109
110
111

112
113
114
115
116

117
118
104
105
106
107
108
109
110

111
112
113
114
115

116
117
118







-
+




-
+



- (OFString *)description
{
	if (_host != nil)
		return [OFString stringWithFormat:
		    @"Binding to port %" @PRIu16 @" on host %@ failed in "
		    @"socket of type %@: %@",
		    _port, _host, [_socket class], of_strerror(_errNo)];
		    _port, _host, [_socket class], OFStrError(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"Binding to port %" @PRIx16 @" for packet type %" @PRIx8
		    @" failed in socket of type %@: %@",
		    _port, _packetType, [_socket class], of_strerror(_errNo)];
		    _port, _packetType, [_socket class], OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFChangeCurrentDirectoryPathFailedException.m from [8ebcf82a75] to [c3f3d9bb60].

58
59
60
61
62
63
64
65

66
67
58
59
60
61
62
63
64

65
66
67







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to change the current directory path to %@: %@",
	    _path, of_strerror(_errNo)];
	    _path, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFConnectionFailedException.m from [55b2b79014] to [847ad9798b].

113
114
115
116
117
118
119
120

121
122
123
124
125
126
127

128
129
130
131
132

133
134
113
114
115
116
117
118
119

120
121
122
123
124
125
126

127
128
129
130
131

132
133
134







-
+






-
+




-
+



- (OFString *)description
{
	if (_host != nil)
		return [OFString stringWithFormat:
		    @"A connection to %@ on port %" @PRIu16 @" could not be "
		    @"established in socket of type %@: %@",
		    _host, _port, [_socket class], of_strerror(_errNo)];
		    _host, _port, [_socket class], OFStrError(_errNo)];
	else if (memcmp(_node, "\0\0\0\0\0", IPX_NODE_LEN) == 0)
		return [OFString stringWithFormat:
		    @"A connection to %02X%02X%02X%02X%02X%02X port %" @PRIu16
		    @" on network %" @PRIX32 " could not be established in "
		    @"socket of type %@: %@",
		    _node[0], _node[1], _node[2], _node[3], _node[4], _node[5],
		    _port, _network, [_socket class], of_strerror(_errNo)];
		    _port, _network, [_socket class], OFStrError(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"A connection could not be established in socket of "
		    @"type %@: %@",
		    [_socket class], of_strerror(_errNo)];
		    [_socket class], OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFCopyItemFailedException.m from [f16ddfd26e] to [4f3c187188].

67
68
69
70
71
72
73
74

75
76
67
68
69
70
71
72
73

74
75
76







-
+



	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"Failed to copy item %@ to %@: %@",
	    _sourceURL, _destinationURL, of_strerror(_errNo)];
	    _sourceURL, _destinationURL, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFCreateDirectoryFailedException.m from [d2f15104e8] to [1ed32763da].

58
59
60
61
62
63
64
65

66
67
58
59
60
61
62
63
64

65
66
67







-
+



	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to create directory %@: %@", _URL, of_strerror(_errNo)];
	    @"Failed to create directory %@: %@", _URL, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFCreateSymbolicLinkFailedException.m from [eb17d03171] to [0a310f1939].

67
68
69
70
71
72
73
74

75
76
67
68
69
70
71
72
73

74
75
76







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to create symbolic link %@ with target %@: %@",
	    _URL, _target, of_strerror(_errNo)];
	    _URL, _target, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFCreateWindowsRegistryKeyFailedException.m from [c06da68133] to [e5fd8452ce].

76
77
78
79
80
81
82
83

84
85
76
77
78
79
80
81
82

83
84
85







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to create subkey at path %@: %@",
	    _path, of_windows_status_to_string(_status)];
	    _path, OFWindowsStatusToString(_status)];
}
@end

Modified src/exceptions/OFDeleteWindowsRegistryKeyFailedException.m from [4d5d00ab16] to [f6719643c7].

63
64
65
66
67
68
69
70

71
72
63
64
65
66
67
68
69

70
71
72







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to delete subkey at path %@: %@",
	    _subkeyPath, of_windows_status_to_string(_status)];
	    _subkeyPath, OFWindowsStatusToString(_status)];
}
@end

Modified src/exceptions/OFDeleteWindowsRegistryValueFailedException.m from [8cc49f26e8] to [d0d9c24736].

63
64
65
66
67
68
69
70

71
72
63
64
65
66
67
68
69

70
71
72







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to delete value named %@: %@",
	    _valueName, of_windows_status_to_string(_status)];
	    _valueName, OFWindowsStatusToString(_status)];
}
@end

Modified src/exceptions/OFException.h from [2793460901] to [7ef0090f31].

170
171
172
173
174
175
176
177

178
179

180
181
182
183
184
185
170
171
172
173
174
175
176

177
178

179
180
181
182
183
184
185







-
+

-
+






 */
- (nullable OFArray OF_GENERIC(OFString *) *)backtrace;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern OFString *of_strerror(int errNo);
extern OFString *OFStrError(int errNo);
#ifdef OF_WINDOWS
extern OFString *of_windows_status_to_string(LSTATUS status);
extern OFString *OFWindowsStatusToString(LSTATUS status);
#endif
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFException.m from [a20480ca4a] to [133314f808].

78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92







-
+







OF_DESTRUCTOR()
{
	OFPlainMutexFree(&mutex);
}
#endif

OFString *
of_strerror(int errNo)
OFStrError(int errNo)
{
	OFString *ret;
#ifdef HAVE_STRERROR_R
	char buffer[256];
#endif

	if (errNo == 0)
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221







-
+







#endif

	return ret;
}

#ifdef OF_WINDOWS
OFString *
of_windows_status_to_string(LSTATUS status)
OFWindowsStatusToString(LSTATUS status)
{
	OFString *string = nil;
	void *buffer;

	if ([OFSystemInfo isWindowsNT]) {
		if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
		    FORMAT_MESSAGE_ALLOCATE_BUFFER |

Modified src/exceptions/OFGetCurrentDirectoryPathFailedException.m from [c7ac43f203] to [df9ee71b64].

45
46
47
48
49
50
51
52

53
54
45
46
47
48
49
50
51

52
53
54







-
+


	return self;
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Getting the current directory path failed: %@",
	    of_strerror(_errNo)];
	    OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFGetOptionFailedException.m from [5a0bdd642f] to [8f4ec296f2].

53
54
55
56
57
58
59
60

61
62
53
54
55
56
57
58
59

60
61
62







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Getting an option in an object of type %@ failed: %@",
	    [_object class], of_strerror(_errNo)];
	    [_object class], OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFGetWindowsRegistryValueFailedException.m from [7dac30760a] to [1e9584387f].

61
62
63
64
65
66
67
68

69
70
61
62
63
64
65
66
67

68
69
70







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to get value named %@: %@",
	    _valueName, of_windows_status_to_string(_status)];
	    _valueName, OFWindowsStatusToString(_status)];
}
@end

Modified src/exceptions/OFLinkFailedException.m from [1249431f65] to [aad9720e68].

67
68
69
70
71
72
73
74

75
76
67
68
69
70
71
72
73

74
75
76







-
+



	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"Failed to link file %@ to %@: %@",
	    _sourceURL, _destinationURL, of_strerror(_errNo)];
	    _sourceURL, _destinationURL, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFListenFailedException.m from [f550e41673] to [076a85098b].

60
61
62
63
64
65
66
67

68
69
60
61
62
63
64
65
66

67
68
69







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to listen in socket of type %@ with a back log of %d: %@",
	    [_socket class], _backlog, of_strerror(_errNo)];
	    [_socket class], _backlog, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFMoveItemFailedException.m from [5859b5070e] to [d1d30c8ee6].

68
69
70
71
72
73
74
75

76
77
68
69
70
71
72
73
74

75
76
77







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to move item at %@ to %@: %@",
	    _sourceURL, _destinationURL, of_strerror(_errNo)];
	    _sourceURL, _destinationURL, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFObserveFailedException.m from [c747f6dbae] to [2a1e03a9a1].

62
63
64
65
66
67
68
69

70
71
62
63
64
65
66
67
68

69
70
71







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"An observer of class %@ failed to observe: %@",
	    _observer.class, of_strerror(_errNo)];
	    _observer.class, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFOpenItemFailedException.m from [90bc6b3814] to [f27f277ad9].

103
104
105
106
107
108
109
110

111
112
113

114
115
103
104
105
106
107
108
109

110
111
112

113
114
115







-
+


-
+


		item = _URL;
	else if (_path != nil)
		item = _path;

	if (_mode != nil)
		return [OFString stringWithFormat:
		    @"Failed to open item %@ with mode %@: %@",
		    item, _mode, of_strerror(_errNo)];
		    item, _mode, OFStrError(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"Failed to open item %@: %@", item, of_strerror(_errNo)];
		    @"Failed to open item %@: %@", item, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFOpenWindowsRegistryKeyFailedException.m from [44e8721e49] to [55725614ec].

72
73
74
75
76
77
78
79

80
81
72
73
74
75
76
77
78

79
80
81







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to open subkey at path %@: %@",
	    _path, of_windows_status_to_string(_status)];
	    _path, OFWindowsStatusToString(_status)];
}
@end

Modified src/exceptions/OFReadFailedException.m from [ac90b3b64d] to [acb3de62d5].

19
20
21
22
23
24
25
26

27
28
19
20
21
22
23
24
25

26
27
28







-
+


#import "OFString.h"

@implementation OFReadFailedException
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to read %zu bytes from an object of type %@: %@",
	    _requestedLength, [_object class], of_strerror(_errNo)];
	    _requestedLength, [_object class], OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFReadOrWriteFailedException.m from [18185f7c97] to [dadaef8eb0].

62
63
64
65
66
67
68
69

70
71
62
63
64
65
66
67
68

69
70
71







-
+


}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to read or write %zu bytes from / to an object of type "
	    @"%@: %@",
	    _requestedLength, [_object class], of_strerror(_errNo)];
	    _requestedLength, [_object class], OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFRemoveItemFailedException.m from [998c78be5a] to [fd424614b6].

58
59
60
61
62
63
64
65

66
67
58
59
60
61
62
63
64

65
66
67







-
+



	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to remove item at URL %@: %@", _URL, of_strerror(_errNo)];
	    @"Failed to remove item at URL %@: %@", _URL, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFRetrieveItemAttributesFailedException.m from [0ad1b990ce] to [44d875971e].

59
60
61
62
63
64
65
66

67
68
59
60
61
62
63
64
65

66
67
68







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to retrieve attributes for item %@: %@",
	    _URL, of_strerror(_errNo)];
	    _URL, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFSandboxActivationFailedException.m from [2bc8a0bd80] to [32c83692ab].

54
55
56
57
58
59
60
61

62
63
54
55
56
57
58
59
60

61
62
63







-
+



	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"The sandbox could not be applied: %@", of_strerror(_errNo)];
	    @"The sandbox could not be applied: %@", OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFSeekFailedException.m from [4afe52f449] to [47b84af63f].

66
67
68
69
70
71
72
73

74
75
66
67
68
69
70
71
72

73
74
75







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Seeking failed in stream of type %@: %@",
	    _stream.class, of_strerror(_errNo)];
	    _stream.class, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFSetItemAttributesFailedException.m from [868fc58c92] to [f92ac392b8].

73
74
75
76
77
78
79
80

81
82
73
74
75
76
77
78
79

80
81
82







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to set attribute %@ for item %@: %@",
	    _failedAttribute, _URL, of_strerror(_errNo)];
	    _failedAttribute, _URL, OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFSetOptionFailedException.m from [8e6ba356a0] to [80d83b74a4].

53
54
55
56
57
58
59
60

61
62
53
54
55
56
57
58
59

60
61
62







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Setting an option in an object of type %@ failed: %@",
	    [_object class], of_strerror(_errNo)];
	    [_object class], OFStrError(_errNo)];
}
@end

Modified src/exceptions/OFSetWindowsRegistryValueFailedException.m from [4495ced091] to [ae444c6b4a].

72
73
74
75
76
77
78
79

80
81
72
73
74
75
76
77
78

79
80
81







-
+


	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to set value named %@ of type %u: %@",
	    _valueName, _type, of_windows_status_to_string(_status)];
	    _valueName, _type, OFWindowsStatusToString(_status)];
}
@end

Modified src/exceptions/OFWriteFailedException.m from [0afa5a091c] to [6f0f1c63f5].

64
65
66
67
68
69
70
71

72
73
64
65
66
67
68
69
70

71
72
73







-
+



- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to write %zu bytes (after %zu bytes written) to an "
	    @"object of type %@: %@",
	    _requestedLength, _bytesWritten, [_object class],
	    of_strerror(_errNo)];
	    OFStrError(_errNo)];
}
@end

Modified src/unicode.h from [713ec05b75] to [fff23a1772].

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
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







-
-
-
-
-
-
+
+
+
+
+
+





-
+

-
+

-
+

-
+

-
+

-
+



 * 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.
 */

#import "OFString.h"

#define OF_UNICODE_UPPERCASE_TABLE_SIZE 0x1EA
#define OF_UNICODE_LOWERCASE_TABLE_SIZE 0x1EA
#define OF_UNICODE_TITLECASE_TABLE_SIZE 0x1EA
#define OF_UNICODE_CASEFOLDING_TABLE_SIZE 0x1EA
#define OF_UNICODE_DECOMPOSITION_TABLE_SIZE 0x2FB
#define OF_UNICODE_DECOMPOSITION_COMPAT_TABLE_SIZE 0x2FB
#define OFUnicodeUppercaseTableSize 0x1EA
#define OFUnicodeLowercaseTableSize 0x1EA
#define OFUnicodeTitlecaseTableSize 0x1EA
#define OFUnicodeCaseFoldingTableSize 0x1EA
#define OFUnicodeDecompositionTableSize 0x2FB
#define OFUnicodeDecompositionCompatTableSize 0x2FB

#ifdef __cplusplus
extern "C" {
#endif
extern const OFUnichar *const _Nonnull
    of_unicode_uppercase_table[OF_UNICODE_UPPERCASE_TABLE_SIZE];
    OFUnicodeUppercaseTable[OFUnicodeUppercaseTableSize];
extern const OFUnichar *const _Nonnull
    of_unicode_lowercase_table[OF_UNICODE_LOWERCASE_TABLE_SIZE];
    OFUnicodeLowercaseTable[OFUnicodeLowercaseTableSize];
extern const OFUnichar *const _Nonnull
    of_unicode_titlecase_table[OF_UNICODE_TITLECASE_TABLE_SIZE];
    OFUnicodeTitlecaseTable[OFUnicodeTitlecaseTableSize];
extern const OFUnichar *const _Nonnull
    of_unicode_casefolding_table[OF_UNICODE_CASEFOLDING_TABLE_SIZE];
    OFUnicodeCaseFoldingTable[OFUnicodeCaseFoldingTableSize];
extern const char *const _Nullable *const _Nonnull
    of_unicode_decomposition_table[OF_UNICODE_DECOMPOSITION_TABLE_SIZE];
    OFUnicodeDecompositionTable[OFUnicodeDecompositionTableSize];
extern const char *const _Nullable *const _Nonnull
    of_unicode_decomposition_compat_table[OF_UNICODE_DECOMPOSITION_COMPAT_TABLE_SIZE];
    OFUnicodeDecompositionCompatTable[OFUnicodeDecompositionCompatTableSize];
#ifdef __cplusplus
}
#endif

Modified src/unicode.m from [5fc3ae74f1] to [a6f5c61cf3].

1731
1732
1733
1734
1735
1736
1737
1738

1739
1740
1741
1742
1743
1744
1745
1731
1732
1733
1734
1735
1736
1737

1738
1739
1740
1741
1742
1743
1744
1745







-
+







	4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319,
	4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327,
	4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335,
	4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343,
	4344, 4345, 4346, 0, 0, 4349, 4350, 4351,
};

static const OFUnichar casefoldingPage0[0x100] = {
static const OFUnichar caseFoldingPage0[0x100] = {
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
1766
1767
1768
1769
1770
1771
1772
1773

1774
1775
1776
1777
1778
1779
1780
1766
1767
1768
1769
1770
1771
1772

1773
1774
1775
1776
1777
1778
1779
1780







-
+







	248, 249, 250, 251, 252, 253, 254, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
};

static const OFUnichar casefoldingPage1[0x100] = {
static const OFUnichar caseFoldingPage1[0x100] = {
	257, 0, 259, 0, 261, 0, 263, 0,
	265, 0, 267, 0, 269, 0, 271, 0,
	273, 0, 275, 0, 277, 0, 279, 0,
	281, 0, 283, 0, 285, 0, 287, 0,
	289, 0, 291, 0, 293, 0, 295, 0,
	297, 0, 299, 0, 301, 0, 303, 0,
	0, 0, 307, 0, 309, 0, 311, 0,
1801
1802
1803
1804
1805
1806
1807
1808

1809
1810
1811
1812
1813
1814
1815
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810
1811
1812
1813
1814
1815







-
+







	0, 474, 0, 476, 0, 0, 479, 0,
	481, 0, 483, 0, 485, 0, 487, 0,
	489, 0, 491, 0, 493, 0, 495, 0,
	0, 499, 499, 0, 501, 0, 405, 447,
	505, 0, 507, 0, 509, 0, 511, 0,
};

static const OFUnichar casefoldingPage3[0x100] = {
static const OFUnichar caseFoldingPage3[0x100] = {
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
1836
1837
1838
1839
1840
1841
1842
1843

1844
1845
1846
1847
1848
1849
1850
1836
1837
1838
1839
1840
1841
1842

1843
1844
1845
1846
1847
1848
1849
1850







-
+







	985, 0, 987, 0, 989, 0, 991, 0,
	993, 0, 995, 0, 997, 0, 999, 0,
	1001, 0, 1003, 0, 1005, 0, 1007, 0,
	954, 961, 0, 0, 952, 949, 0, 1016,
	0, 1010, 1019, 0, 0, 891, 892, 893,
};

static const OFUnichar casefoldingPage19[0x100] = {
static const OFUnichar caseFoldingPage19[0x100] = {
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
1871
1872
1873
1874
1875
1876
1877
1878

1879
1880
1881
1882
1883
1884
1885
1871
1872
1873
1874
1875
1876
1877

1878
1879
1880
1881
1882
1883
1884
1885







-
+







	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	5104, 5105, 5106, 5107, 5108, 5109, 0, 0,
};

static const OFUnichar casefoldingPage28[0x100] = {
static const OFUnichar caseFoldingPage28[0x100] = {
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
1906
1907
1908
1909
1910
1911
1912
1913

1914
1915
1916
1917
1918
1919
1920
1906
1907
1908
1909
1910
1911
1912

1913
1914
1915
1916
1917
1918
1919
1920







-
+







	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
};

static const OFUnichar casefoldingPage30[0x100] = {
static const OFUnichar caseFoldingPage30[0x100] = {
	7681, 0, 7683, 0, 7685, 0, 7687, 0,
	7689, 0, 7691, 0, 7693, 0, 7695, 0,
	7697, 0, 7699, 0, 7701, 0, 7703, 0,
	7705, 0, 7707, 0, 7709, 0, 7711, 0,
	7713, 0, 7715, 0, 7717, 0, 7719, 0,
	7721, 0, 7723, 0, 7725, 0, 7727, 0,
	7729, 0, 7731, 0, 7733, 0, 7735, 0,
1941
1942
1943
1944
1945
1946
1947
1948

1949
1950
1951
1952
1953
1954
1955
1941
1942
1943
1944
1945
1946
1947

1948
1949
1950
1951
1952
1953
1954
1955







-
+







	7897, 0, 7899, 0, 7901, 0, 7903, 0,
	7905, 0, 7907, 0, 7909, 0, 7911, 0,
	7913, 0, 7915, 0, 7917, 0, 7919, 0,
	7921, 0, 7923, 0, 7925, 0, 7927, 0,
	7929, 0, 7931, 0, 7933, 0, 7935, 0,
};

static const OFUnichar casefoldingPage31[0x100] = {
static const OFUnichar caseFoldingPage31[0x100] = {
	0, 0, 0, 0, 0, 0, 0, 0,
	7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943,
	0, 0, 0, 0, 0, 0, 0, 0,
	7952, 7953, 7954, 7955, 7956, 7957, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975,
	0, 0, 0, 0, 0, 0, 0, 0,
1976
1977
1978
1979
1980
1981
1982
1983

1984
1985
1986
1987
1988
1989
1990
1976
1977
1978
1979
1980
1981
1982

1983
1984
1985
1986
1987
1988
1989
1990







-
+







	8144, 8145, 8054, 8055, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	8160, 8161, 8058, 8059, 8165, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	8056, 8057, 8060, 8061, 8179, 0, 0, 0,
};

static const OFUnichar casefoldingPage171[0x100] = {
static const OFUnichar caseFoldingPage171[0x100] = {
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
12360
12361
12362
12363
12364
12365
12366
12367

12368
12369
12370
12371
12372
12373
12374
12360
12361
12362
12363
12364
12365
12366

12367
12368
12369
12370
12371
12372
12373
12374







-
+







	"\x36", "\x37",
	"\x38", "\x39",
	NULL, NULL,
	NULL, NULL,
	NULL, NULL,
};

const OFUnichar *const of_unicode_uppercase_table[0x1EA] = {
const OFUnichar *const OFUnicodeUppercaseTable[0x1EA] = {
	uppercasePage0, uppercasePage1, uppercasePage2, uppercasePage3,
	uppercasePage4, uppercasePage5, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	uppercasePage16, emptyPage, emptyPage, uppercasePage19,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
12486
12487
12488
12489
12490
12491
12492
12493

12494
12495
12496
12497
12498
12499
12500
12486
12487
12488
12489
12490
12491
12492

12493
12494
12495
12496
12497
12498
12499
12500







-
+







	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, uppercasePage489
};

const OFUnichar *const of_unicode_lowercase_table[0x1EA] = {
const OFUnichar *const OFUnicodeLowercaseTable[0x1EA] = {
	lowercasePage0, lowercasePage1, lowercasePage2, lowercasePage3,
	lowercasePage4, lowercasePage5, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	lowercasePage16, emptyPage, emptyPage, lowercasePage19,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
12612
12613
12614
12615
12616
12617
12618
12619

12620
12621
12622
12623
12624
12625
12626
12612
12613
12614
12615
12616
12617
12618

12619
12620
12621
12622
12623
12624
12625
12626







-
+







	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, lowercasePage489
};

const OFUnichar *const of_unicode_titlecase_table[0x1EA] = {
const OFUnichar *const OFUnicodeTitlecaseTable[0x1EA] = {
	uppercasePage0, titlecasePage1, uppercasePage2, uppercasePage3,
	uppercasePage4, uppercasePage5, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	titlecasePage16, emptyPage, emptyPage, uppercasePage19,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747



12748
12749
12750
12751
12752

12753
12754
12755
12756


12757
12758
12759
12760
12761
12762
12763
12738
12739
12740
12741
12742
12743
12744



12745
12746
12747
12748
12749
12750
12751

12752
12753
12754


12755
12756
12757
12758
12759
12760
12761
12762
12763







-
-
-
+
+
+




-
+


-
-
+
+







	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage, emptyPage,
	emptyPage, uppercasePage489
};

const OFUnichar *const of_unicode_casefolding_table[0x1EA] = {
	casefoldingPage0, casefoldingPage1, lowercasePage2,
	casefoldingPage3, lowercasePage4, lowercasePage5,
const OFUnichar *const OFUnicodeCaseFoldingTable[0x1EA] = {
	caseFoldingPage0, caseFoldingPage1, lowercasePage2,
	caseFoldingPage3, lowercasePage4, lowercasePage5,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, lowercasePage16, emptyPage,
	emptyPage, casefoldingPage19, emptyPage,
	emptyPage, caseFoldingPage19, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, casefoldingPage28, emptyPage,
	casefoldingPage30, casefoldingPage31, emptyPage,
	emptyPage, caseFoldingPage28, emptyPage,
	caseFoldingPage30, caseFoldingPage31, emptyPage,
	lowercasePage33, emptyPage, emptyPage,
	lowercasePage36, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, lowercasePage44,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
12796
12797
12798
12799
12800
12801
12802
12803

12804
12805
12806
12807
12808
12809
12810
12796
12797
12798
12799
12800
12801
12802

12803
12804
12805
12806
12807
12808
12809
12810







-
+







	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, lowercasePage166, lowercasePage167,
	emptyPage, emptyPage, emptyPage,
	casefoldingPage171, emptyPage, emptyPage,
	caseFoldingPage171, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
12905
12906
12907
12908
12909
12910
12911
12912

12913
12914
12915
12916
12917
12918
12919
12905
12906
12907
12908
12909
12910
12911

12912
12913
12914
12915
12916
12917
12918
12919







-
+







	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	emptyPage, emptyPage, emptyPage,
	lowercasePage489
};

const char *const *of_unicode_decomposition_table[0x2FB] = {
const char *const *OFUnicodeDecompositionTable[0x2FB] = {
	decompositionPage0, decompositionPage1, decompositionPage2,
	decompositionPage3, decompositionPage4, emptyDecompositionPage,
	decompositionPage6, emptyDecompositionPage, emptyDecompositionPage,
	decompositionPage9, decompositionPage10, decompositionPage11,
	decompositionPage12, decompositionPage13, emptyDecompositionPage,
	decompositionPage15, decompositionPage16, emptyDecompositionPage,
	emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage,
13163
13164
13165
13166
13167
13168
13169
13170

13171
13172
13173
13174
13175
13176
13177
13163
13164
13165
13166
13167
13168
13169

13170
13171
13172
13173
13174
13175
13176
13177







-
+







	emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage,
	emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage,
	emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage,
	emptyDecompositionPage, decompositionPage760, decompositionPage761,
	decompositionPage762
};

const char *const *of_unicode_decomposition_compat_table[0x2FB] = {
const char *const *OFUnicodeDecompositionCompatTable[0x2FB] = {
	decompCompatPage0, decompCompatPage1, decompCompatPage2,
	decompCompatPage3, decompositionPage4, decompCompatPage5,
	decompCompatPage6, emptyDecompositionPage, emptyDecompositionPage,
	decompositionPage9, decompositionPage10, decompositionPage11,
	decompCompatPage12, decompCompatPage13, decompCompatPage14,
	decompCompatPage15, decompCompatPage16, emptyDecompositionPage,
	emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage,

Modified tests/OFDNSResolverTests.m from [0af53b3697] to [1d2ed3ff32].

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
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







-
+












-
+


-
+


-
+


-
+


-
+


-
+


-
+



-
+


-
+






@implementation TestsAppDelegate (OFDNSResolverTests)
- (void)DNSResolverTests
{
	void *pool = objc_autoreleasePoolPush();
	OFDNSResolver *resolver = [OFDNSResolver resolver];
	OFMutableString *staticHosts = [OFMutableString string];

	[of_stdout setForegroundColor: [OFColor lime]];
	[OFStdOut setForegroundColor: [OFColor lime]];

	for (OFString *host in resolver.staticHosts) {
		OFString *IPs;

		if (staticHosts.length > 0)
			[staticHosts appendString: @"; "];

		IPs = [[resolver.staticHosts objectForKey: host]
		    componentsJoinedByString: @", "];

		[staticHosts appendFormat: @"%@=(%@)", host, IPs];
	}
	[of_stdout writeFormat: @"[OFDNSResolver] Static hosts: %@\n",
	[OFStdOut writeFormat: @"[OFDNSResolver] Static hosts: %@\n",
	    staticHosts];

	[of_stdout writeFormat: @"[OFDNSResolver] Name servers: %@\n",
	[OFStdOut writeFormat: @"[OFDNSResolver] Name servers: %@\n",
	    [resolver.nameServers componentsJoinedByString: @", "]];

	[of_stdout writeFormat: @"[OFDNSResolver] Local domain: %@\n",
	[OFStdOut writeFormat: @"[OFDNSResolver] Local domain: %@\n",
	    resolver.localDomain];

	[of_stdout writeFormat: @"[OFDNSResolver] Search domains: %@\n",
	[OFStdOut writeFormat: @"[OFDNSResolver] Search domains: %@\n",
	    [resolver.searchDomains componentsJoinedByString: @", "]];

	[of_stdout writeFormat: @"[OFDNSResolver] Timeout: %lf\n",
	[OFStdOut writeFormat: @"[OFDNSResolver] Timeout: %lf\n",
	    resolver.timeout];

	[of_stdout writeFormat: @"[OFDNSResolver] Max attempts: %u\n",
	[OFStdOut writeFormat: @"[OFDNSResolver] Max attempts: %u\n",
	    resolver.maxAttempts];

	[of_stdout writeFormat:
	[OFStdOut writeFormat:
	    @"[OFDNSResolver] Min number of dots in absolute name: %u\n",
	    resolver.minNumberOfDotsInAbsoluteName];

	[of_stdout writeFormat: @"[OFDNSResolver] Uses TCP: %u\n",
	[OFStdOut writeFormat: @"[OFDNSResolver] Uses TCP: %u\n",
	    resolver.usesTCP];

	[of_stdout writeFormat:
	[OFStdOut writeFormat:
	    @"[OFDNSResolver] Config reload interval: %lf\n",
	    resolver.configReloadInterval];

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFIPXSocketTests.m from [2def7aa281] to [d96f547fea].

33
34
35
36
37
38
39
40
41


42
43
44
45
46
47


48
49
50
51
52
53
54
33
34
35
36
37
38
39


40
41
42
43
44
45


46
47
48
49
50
51
52
53
54







-
-
+
+




-
-
+
+








	@try {
		TEST(@"-[bindToPort:packetType:]",
		    R(address1 = [sock bindToPort: 0 packetType: 0]))
	} @catch (OFBindFailedException *e) {
		switch (e.errNo) {
		case EAFNOSUPPORT:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFIPXSocket] -[bindToPort:packetType:]: "
			    @"IPX unsupported, skipping tests"];
			break;
		case EADDRNOTAVAIL:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFIPXSocket] -[bindToPort:packetType:]: "
			    @"IPX not configured, skipping tests"];
			break;
		default:
			@throw e;
		}

Modified tests/OFLocaleTests.m from [958923ab2a] to [16fe524ac5].

18
19
20
21
22
23
24
25

26
27

28
29
30

31
32
33

34
35
36

37
38
39
40
41
18
19
20
21
22
23
24

25
26

27
28
29

30
31
32

33
34
35

36
37
38
39
40
41







-
+

-
+


-
+


-
+


-
+





#import "TestsAppDelegate.h"

@implementation TestsAppDelegate (OFLocaleTests)
- (void)localeTests
{
	void *pool = objc_autoreleasePoolPush();

	[of_stdout setForegroundColor: [OFColor lime]];
	[OFStdOut setForegroundColor: [OFColor lime]];

	[of_stdout writeFormat: @"[OFLocale] Language: %@\n",
	[OFStdOut writeFormat: @"[OFLocale] Language: %@\n",
	    [OFLocale language]];

	[of_stdout writeFormat: @"[OFLocale] Territory: %@\n",
	[OFStdOut writeFormat: @"[OFLocale] Territory: %@\n",
	    [OFLocale territory]];

	[of_stdout writeFormat: @"[OFLocale] Encoding: %@\n",
	[OFStdOut writeFormat: @"[OFLocale] Encoding: %@\n",
	    OFStringEncodingName([OFLocale encoding])];

	[of_stdout writeFormat: @"[OFLocale] Decimal point: %@\n",
	[OFStdOut writeFormat: @"[OFLocale] Decimal point: %@\n",
	    [OFLocale decimalPoint]];

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFMethodSignatureTests.m from [465deaed93] to [364a3b706f].

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
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







-
-
+
+


-
-
+
+




-
-
+
+



-
-
+
+


-
-
+
+


-
-
+
+


-
-
+
+


-
-
+
+




-
-
+
+



-
-
+
+


-
-
+
+


-
-
+
+





	    OFInvalidFormatException,
	    [OFMethodSignature signatureWithObjCTypes: "0"])

	EXPECT_EXCEPTION(@"-[signatureWithObjCTypes:] #6",
	    OFInvalidFormatException,
	    [OFMethodSignature signatureWithObjCTypes: "{{}0"])

	TEST(@"of_sizeof_type_encoding() #1",
	    of_sizeof_type_encoding(@encode(struct test1_struct)) ==
	TEST(@"OFSizeOfTypeEncoding() #1",
	    OFSizeOfTypeEncoding(@encode(struct test1_struct)) ==
	    sizeof(struct test1_struct))

	TEST(@"of_sizeof_type_encoding() #2",
	    of_sizeof_type_encoding(@encode(struct test2_struct)) ==
	TEST(@"OFSizeOfTypeEncoding() #2",
	    OFSizeOfTypeEncoding(@encode(struct test2_struct)) ==
	    sizeof(struct test2_struct))

#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) && \
    OF_GCC_VERSION >= 402
	TEST(@"of_sizeof_type_encoding() #3",
	    of_sizeof_type_encoding(@encode(struct test3_struct)) ==
	TEST(@"OFSizeOfTypeEncoding() #3",
	    OFSizeOfTypeEncoding(@encode(struct test3_struct)) ==
	    sizeof(struct test3_struct))
#endif

	TEST(@"of_sizeof_type_encoding() #4",
	    of_sizeof_type_encoding(@encode(union test3_union)) ==
	TEST(@"OFSizeOfTypeEncoding() #4",
	    OFSizeOfTypeEncoding(@encode(union test3_union)) ==
	    sizeof(union test3_union))

	TEST(@"of_sizeof_type_encoding() #5",
	    of_sizeof_type_encoding(@encode(union test4_union)) ==
	TEST(@"OFSizeOfTypeEncoding() #5",
	    OFSizeOfTypeEncoding(@encode(union test4_union)) ==
	    sizeof(union test4_union))

	TEST(@"of_sizeof_type_encoding() #6",
	    of_sizeof_type_encoding(@encode(struct test1_struct [5])) ==
	TEST(@"OFSizeOfTypeEncoding() #6",
	    OFSizeOfTypeEncoding(@encode(struct test1_struct [5])) ==
	    sizeof(struct test1_struct [5]))

	TEST(@"of_alignof_type_encoding() #1",
	    of_alignof_type_encoding(@encode(struct test1_struct)) ==
	TEST(@"OFAlignmentOfTypeEncoding() #1",
	    OFAlignmentOfTypeEncoding(@encode(struct test1_struct)) ==
	    OF_ALIGNOF(struct test1_struct))

	TEST(@"of_alignof_type_encoding() #2",
	    of_alignof_type_encoding(@encode(struct test2_struct)) ==
	TEST(@"OFAlignmentOfTypeEncoding() #2",
	    OFAlignmentOfTypeEncoding(@encode(struct test2_struct)) ==
	    OF_ALIGNOF(struct test2_struct))

#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) && \
    OF_GCC_VERSION >= 402
	TEST(@"of_alignof_type_encoding() #3",
	    of_alignof_type_encoding(@encode(struct test3_struct)) ==
	TEST(@"OFAlignmentOfTypeEncoding() #3",
	    OFAlignmentOfTypeEncoding(@encode(struct test3_struct)) ==
	    OF_ALIGNOF(struct test3_struct))
#endif

	TEST(@"of_alignof_type_encoding() #4",
	    of_alignof_type_encoding(@encode(union test3_union)) ==
	TEST(@"OFAlignmentOfTypeEncoding() #4",
	    OFAlignmentOfTypeEncoding(@encode(union test3_union)) ==
	    OF_ALIGNOF(union test3_union))

	TEST(@"of_alignof_type_encoding() #5",
	    of_alignof_type_encoding(@encode(union test4_union)) ==
	TEST(@"OFAlignmentOfTypeEncoding() #5",
	    OFAlignmentOfTypeEncoding(@encode(union test4_union)) ==
	    OF_ALIGNOF(union test4_union))

	TEST(@"of_alignof_type_encoding() #6",
	    of_alignof_type_encoding(@encode(struct test1_struct [5])) ==
	TEST(@"OFAlignmentOfTypeEncoding() #6",
	    OFAlignmentOfTypeEncoding(@encode(struct test1_struct [5])) ==
	    OF_ALIGNOF(struct test1_struct [5]))

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFSPXSocketTests.m from [cfe6c1219c] to [8af68629fd].

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
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







-
-
+
+




-
-
+
+




-
-
+
+








	@try {
		TEST(@"-[bindToPort:]",
		    R(address1 = [sockServer bindToPort: 0]))
	} @catch (OFBindFailedException *e) {
		switch (e.errNo) {
		case EAFNOSUPPORT:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFSPXSocket] -[bindToPort:]: "
			    @"IPX unsupported, skipping tests"];
			break;
		case ESOCKTNOSUPPORT:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFSPXSocket] -[bindToPort:]: "
			    @"SPX unsupported, skipping tests"];
			break;
		case EADDRNOTAVAIL:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFSPXSocket] -[bindToPort:]: "
			    @"IPX not configured, skipping tests"];
			break;
		default:
			@throw e;
		}

168
169
170
171
172
173
174
175
176


177
178
179
180
181
182
183
184
185
186
187
188
168
169
170
171
172
173
174


175
176
177
178
179
180
181
182
183
184
185
186
187
188







-
-
+
+












		    [OFDate dateWithTimeIntervalSinceNow: 2]];

		TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]",
		    delegate->_accepted && delegate->_connected)
	} @catch (OFObserveFailedException *e) {
		switch (e.errNo) {
		case ENOTSOCK:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFSPXSocket] -[asyncAccept] & "
			    @"-[asyncConnectToNode:network:port:]: select() "
			    @"not supported for SPX, skipping test"];
			break;
		default:
			@throw e;
		}
	}

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFSPXStreamSocketTests.m from [9626f93ed7] to [e27033149d].

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
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







-
-
+
+




-
-
+
+




-
-
+
+








	@try {
		TEST(@"-[bindToPort:]",
		    R(address1 = [sockServer bindToPort: 0]))
	} @catch (OFBindFailedException *e) {
		switch (e.errNo) {
		case EAFNOSUPPORT:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFSPXStreamSocket] -[bindToPort:]: "
			    @"IPX unsupported, skipping tests"];
			break;
		case ESOCKTNOSUPPORT:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFSPXStreamSocket] -[bindToPort:]: "
			    @"SPX unsupported, skipping tests"];
			break;
		case EADDRNOTAVAIL:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFSPXStreamSocket] -[bindToPort:]: "
			    @"IPX not configured, skipping tests"];
			break;
		default:
			@throw e;
		}

171
172
173
174
175
176
177
178
179


180
181
182
183
184
185
186
187
188
189
190
191
171
172
173
174
175
176
177


178
179
180
181
182
183
184
185
186
187
188
189
190
191







-
-
+
+












		    [OFDate dateWithTimeIntervalSinceNow: 2]];

		TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]",
		    delegate->_accepted && delegate->_connected)
	} @catch (OFObserveFailedException *e) {
		switch (e.errNo) {
		case ENOTSOCK:
			[of_stdout setForegroundColor: [OFColor lime]];
			[of_stdout writeLine:
			[OFStdOut setForegroundColor: [OFColor lime]];
			[OFStdOut writeLine:
			    @"\r[OFSPXStreamSocket] -[asyncAccept] & "
			    @"-[asyncConnectToNode:network:port:]: select() "
			    @"not supported for SPX, skipping test"];
			break;
		default:
			@throw e;
		}
	}

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFStringTests.m from [5086f0db86] to [40fec06275].

1190
1191
1192
1193
1194
1195
1196
1197

1198
1199
1200

1201
1202
1203
1204
1205

1206
1207
1208

1209
1210
1211
1212
1213
1214
1215
1190
1191
1192
1193
1194
1195
1196

1197
1198
1199

1200
1201
1202
1203
1204

1205
1206
1207

1208
1209
1210
1211
1212
1213
1214
1215







-
+


-
+




-
+


-
+








#ifdef OF_BIG_ENDIAN
# define SWAPPED_BYTE_ORDER OFByteOrderLittleEndian
#else
# define SWAPPED_BYTE_ORDER OFByteOrderBigEndian
#endif
	TEST(@"-[UTF16String]", (u16a = C(@"fööbär🀺").UTF16String) &&
	    !memcmp(u16a, utf16str + 1, of_string_utf16_length(utf16str) * 2) &&
	    !memcmp(u16a, utf16str + 1, OFUTF16StringLength(utf16str) * 2) &&
	    (u16a = [C(@"fööbär🀺")
	    UTF16StringWithByteOrder: SWAPPED_BYTE_ORDER]) &&
	    !memcmp(u16a, sutf16str + 1, of_string_utf16_length(sutf16str) * 2))
	    !memcmp(u16a, sutf16str + 1, OFUTF16StringLength(sutf16str) * 2))

	TEST(@"-[UTF16StringLength]", C(@"fööbär🀺").UTF16StringLength == 8)

	TEST(@"-[UTF32String]", (ua = C(@"fööbär🀺").UTF32String) &&
	    !memcmp(ua, ucstr + 1, of_string_utf32_length(ucstr) * 4) &&
	    !memcmp(ua, ucstr + 1, OFUTF32StringLength(ucstr) * 4) &&
	    (ua = [C(@"fööbär🀺") UTF32StringWithByteOrder:
	    SWAPPED_BYTE_ORDER]) &&
	    !memcmp(ua, sucstr + 1, of_string_utf32_length(sucstr) * 4))
	    !memcmp(ua, sucstr + 1, OFUTF32StringLength(sucstr) * 4))
#undef SWAPPED_BYTE_ORDER

	TEST(@"-[stringByMD5Hashing]", [C(@"asdfoobar").stringByMD5Hashing
	    isEqual: @"184dce2ec49b5422c7cfd8728864db4c"])

	TEST(@"-[stringByRIPEMD160Hashing]",
	    [C(@"asdfoobar").stringByRIPEMD160Hashing

Modified tests/OFSystemInfoTests.m from [c560db3946] to [23b6100c57].

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
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







-
+

-
+


-
+


-
+


-
+


-
+


-
+


-
+









-
+







-
+



-
+


-
+



-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+




-
+






- (void)systemInfoTests
{
	void *pool = objc_autoreleasePoolPush();
#ifdef OF_HAVE_FILES
	OFString *userConfigPath, *userDataPath;
#endif

	[of_stdout setForegroundColor: [OFColor lime]];
	[OFStdOut setForegroundColor: [OFColor lime]];

	[of_stdout writeFormat: @"[OFSystemInfo] Page size: %zd\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Page size: %zd\n",
	    [OFSystemInfo pageSize]];

	[of_stdout writeFormat: @"[OFSystemInfo] Number of CPUs: %zd\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Number of CPUs: %zd\n",
	    [OFSystemInfo numberOfCPUs]];

	[of_stdout writeFormat: @"[OFSystemInfo] ObjFW version: %@\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] ObjFW version: %@\n",
	    [OFSystemInfo ObjFWVersion]];

	[of_stdout writeFormat: @"[OFSystemInfo] ObjFW version major: %u\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] ObjFW version major: %u\n",
	    [OFSystemInfo ObjFWVersionMajor]];

	[of_stdout writeFormat: @"[OFSystemInfo] ObjFW version minor: %u\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] ObjFW version minor: %u\n",
	    [OFSystemInfo ObjFWVersionMinor]];

	[of_stdout writeFormat: @"[OFSystemInfo] Operating system name: %@\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Operating system name: %@\n",
	    [OFSystemInfo operatingSystemName]];

	[of_stdout writeFormat:
	[OFStdOut writeFormat:
	    @"[OFSystemInfo] Operating system version: %@\n",
	    [OFSystemInfo operatingSystemVersion]];

#ifdef OF_HAVE_FILES
	@try {
		userConfigPath = [OFSystemInfo userConfigPath];
	} @catch (OFNotImplementedException *e) {
		userConfigPath = @"Not implemented";
	}
	[of_stdout writeFormat: @"[OFSystemInfo] User config path: %@\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] User config path: %@\n",
	    userConfigPath];

	@try {
		userDataPath = [OFSystemInfo userDataPath];
	} @catch (OFNotImplementedException *e) {
		userDataPath = @"Not implemented";
	}
	[of_stdout writeFormat: @"[OFSystemInfo] User data path: %@\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] User data path: %@\n",
	    userDataPath];
#endif

	[of_stdout writeFormat: @"[OFSystemInfo] CPU vendor: %@\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] CPU vendor: %@\n",
	    [OFSystemInfo CPUVendor]];

	[of_stdout writeFormat: @"[OFSystemInfo] CPU model: %@\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] CPU model: %@\n",
	    [OFSystemInfo CPUModel]];

#if defined(OF_X86_64) || defined(OF_X86)
	[of_stdout writeFormat: @"[OFSystemInfo] Supports MMX: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports MMX: %d\n",
	    [OFSystemInfo supportsMMX]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports SSE: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE: %d\n",
	    [OFSystemInfo supportsSSE]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports SSE2: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE2: %d\n",
	    [OFSystemInfo supportsSSE2]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports SSE3: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE3: %d\n",
	    [OFSystemInfo supportsSSE3]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports SSSE3: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports SSSE3: %d\n",
	    [OFSystemInfo supportsSSSE3]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports SSE4.1: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE4.1: %d\n",
	    [OFSystemInfo supportsSSE41]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports SSE4.2: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE4.2: %d\n",
	    [OFSystemInfo supportsSSE42]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports AVX: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports AVX: %d\n",
	    [OFSystemInfo supportsAVX]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports AVX2: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports AVX2: %d\n",
	    [OFSystemInfo supportsAVX2]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports AES-NI: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports AES-NI: %d\n",
	    [OFSystemInfo supportsAESNI]];

	[of_stdout writeFormat: @"[OFSystemInfo] Supports SHA extensions: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports SHA extensions: %d\n",
	    [OFSystemInfo supportsSHAExtensions]];
#endif

#ifdef OF_POWERPC
	[of_stdout writeFormat: @"[OFSystemInfo] Supports AltiVec: %d\n",
	[OFStdOut writeFormat: @"[OFSystemInfo] Supports AltiVec: %d\n",
	    [OFSystemInfo supportsAltiVec]];
#endif

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/TestsAppDelegate.m from [ec5b8946c4] to [0b419cd689].

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
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
252
253
254
255
256
257
258
259
260
261
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
287
288



289
290

291
292
293
294
295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
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
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
252
253
254
255
256
257
258
259
260


261
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
287
288

289
290
291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308







-
+








-
-
-
+
+
+


-
-
+
+












-
-
+
+








-
-
+
+














-
-
+







-
-
-
+
+
+

-
+





-
-
-
-
+
+
+
+

-
+





-
-
-
-
+
+
+
+


-
-
+
+











-
-
+
+















-
-
+
+









-
-
+
+











-
-
-
+
+
+

-
+











-
+








	consoleInit(GFX_TOP, NULL);
#endif

#if defined(OF_WII) || defined(OF_PSP) || defined(OF_NINTENDO_DS) || \
	defined(OF_NINTENDO_3DS)
	@try {
		return of_application_main(&argc, &argv,
		return OFApplicationMain(&argc, &argv,
		    [[TestsAppDelegate alloc] init]);
	} @catch (id e) {
		OFString *string = [OFString stringWithFormat:
		    @"\nRuntime error: Unhandled exception:\n%@\n", e];
		OFString *backtrace = [OFString stringWithFormat:
		    @"\nBacktrace:\n  %@\n\n",
		    [[e backtrace] componentsJoinedByString: @"\n  "]];

		[of_stdout setForegroundColor: [OFColor red]];
		[of_stdout writeString: string];
		[of_stdout writeString: backtrace];
		[OFStdOut setForegroundColor: [OFColor red]];
		[OFStdOut writeString: string];
		[OFStdOut writeString: backtrace];

# if defined(OF_WII)
		[of_stdout reset];
		[of_stdout writeString: @"Press home button to exit!"];
		[OFStdOut reset];
		[OFStdOut writeString: @"Press home button to exit!"];

		for (;;) {
			WPAD_ScanPads();

			if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
				[OFApplication terminateWithStatus: 1];

			VIDEO_WaitVSync();
		}
# elif defined(OF_PSP)
		sceKernelSleepThreadCB();
# elif defined(OF_NINTENDO_DS)
		[of_stdout reset];
		[of_stdout writeString: @"Press start button to exit!"];
		[OFStdOut reset];
		[OFStdOut writeString: @"Press start button to exit!"];

		for (;;) {
			swiWaitForVBlank();
			scanKeys();
			if (keysDown() & KEY_START)
				[OFApplication terminateWithStatus: 1];
		}
# elif defined(OF_NINTENDO_3DS)
		[of_stdout reset];
		[of_stdout writeString: @"Press start button to exit!"];
		[OFStdOut reset];
		[OFStdOut writeString: @"Press start button to exit!"];

		for (;;) {
			hidScanInput();

			if (hidKeysDown() & KEY_START)
				[OFApplication terminateWithStatus: 1];

			gspWaitForVBlank();
		}
# else
		abort();
# endif
	}
#else
	return of_application_main(&argc, &argv,
	    [[TestsAppDelegate alloc] init]);
	return OFApplicationMain(&argc, &argv, [[TestsAppDelegate alloc] init]);
#endif
}

@implementation TestsAppDelegate
- (void)outputTesting: (OFString *)test
	     inModule: (OFString *)module
{
	if (of_stdout.hasTerminal) {
		[of_stdout setForegroundColor: [OFColor yellow]];
		[of_stdout writeFormat: @"[%@] %@: testing...", module, test];
	if (OFStdOut.hasTerminal) {
		[OFStdOut setForegroundColor: [OFColor yellow]];
		[OFStdOut writeFormat: @"[%@] %@: testing...", module, test];
	} else
		[of_stdout writeFormat: @"[%@] %@: ", module, test];
		[OFStdOut writeFormat: @"[%@] %@: ", module, test];
}

- (void)outputSuccess: (OFString *)test
	     inModule: (OFString *)module
{
	if (of_stdout.hasTerminal) {
		[of_stdout setForegroundColor: [OFColor lime]];
		[of_stdout eraseLine];
		[of_stdout writeFormat: @"\r[%@] %@: ok\n", module, test];
	if (OFStdOut.hasTerminal) {
		[OFStdOut setForegroundColor: [OFColor lime]];
		[OFStdOut eraseLine];
		[OFStdOut writeFormat: @"\r[%@] %@: ok\n", module, test];
	} else
		[of_stdout writeLine: @"ok"];
		[OFStdOut writeLine: @"ok"];
}

- (void)outputFailure: (OFString *)test
	     inModule: (OFString *)module
{
	if (of_stdout.hasTerminal) {
		[of_stdout setForegroundColor: [OFColor red]];
		[of_stdout eraseLine];
		[of_stdout writeFormat: @"\r[%@] %@: failed\n", module, test];
	if (OFStdOut.hasTerminal) {
		[OFStdOut setForegroundColor: [OFColor red]];
		[OFStdOut eraseLine];
		[OFStdOut writeFormat: @"\r[%@] %@: failed\n", module, test];

#ifdef OF_WII
		[of_stdout reset];
		[of_stdout writeLine: @"Press A to continue!"];
		[OFStdOut reset];
		[OFStdOut writeLine: @"Press A to continue!"];

		for (;;) {
			WPAD_ScanPads();

			if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A)
				return;

			VIDEO_WaitVSync();
		}
#endif
#ifdef OF_PSP
		[of_stdout reset];
		[of_stdout writeLine: @"Press X to continue!"];
		[OFStdOut reset];
		[OFStdOut writeLine: @"Press X to continue!"];

		for (;;) {
			SceCtrlData pad;

			sceCtrlReadBufferPositive(&pad, 1);
			if (pad.Buttons & PSP_CTRL_CROSS) {
				for (;;) {
					sceCtrlReadBufferPositive(&pad, 1);
					if (!(pad.Buttons & PSP_CTRL_CROSS))
						return;
				}
			}
		}
#endif
#ifdef OF_NINTENDO_DS
		[of_stdout reset];
		[of_stdout writeString: @"Press A to continue!"];
		[OFStdOut reset];
		[OFStdOut writeString: @"Press A to continue!"];

		for (;;) {
			swiWaitForVBlank();
			scanKeys();
			if (keysDown() & KEY_A)
				break;
		}
#endif
#ifdef OF_NINTENDO_3DS
		[of_stdout reset];
		[of_stdout writeString: @"Press A to continue!"];
		[OFStdOut reset];
		[OFStdOut writeString: @"Press A to continue!"];

		for (;;) {
			hidScanInput();

			if (hidKeysDown() & KEY_A)
				break;

			gspWaitForVBlank();
		}
#endif

		[of_stdout writeString: @"\r"];
		[of_stdout reset];
		[of_stdout eraseLine];
		[OFStdOut writeString: @"\r"];
		[OFStdOut reset];
		[OFStdOut eraseLine];
	} else
		[of_stdout writeLine: @"failed"];
		[OFStdOut writeLine: @"failed"];
}

- (void)applicationDidFinishLaunching
{
#if defined(OF_IOS) && defined(OF_HAVE_FILES)
	CFBundleRef mainBundle = CFBundleGetMainBundle();
	CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
	UInt8 resourcesPath[PATH_MAX];

	if (!CFURLGetFileSystemRepresentation(resourcesURL, true, resourcesPath,
	    PATH_MAX)) {
		[of_stderr writeString: @"Failed to locate resources!\n"];
		[OFStdErr writeString: @"Failed to locate resources!\n"];
		[OFApplication terminateWithStatus: 1];
	}

	[[OFFileManager defaultManager] changeCurrentDirectoryPath:
	    [OFString stringWithUTF8String: (const char *)resourcesPath]];
#endif
#if defined(OF_WII) && defined(OF_HAVE_FILES)
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
428
429
430
431
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
428
429
430







-
+


-
+


-
+










-
+



-
+








-
+








#ifdef OF_HAVE_SOCKETS
	[self DNSResolverTests];
#endif
	[self systemInfoTests];
	[self localeTests];

	[of_stdout reset];
	[OFStdOut reset];

#if defined(OF_IOS)
	[of_stdout writeFormat: @"%d tests failed!", _fails];
	[OFStdOut writeFormat: @"%d tests failed!", _fails];
	[OFApplication terminateWithStatus: _fails];
#elif defined(OF_WII)
	[of_stdout writeString: @"Press home button to exit!"];
	[OFStdOut writeString: @"Press home button to exit!"];

	for (;;) {
		WPAD_ScanPads();

		if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
			[OFApplication terminateWithStatus: _fails];

		VIDEO_WaitVSync();
	}
#elif defined(OF_PSP)
	[of_stdout writeFormat: @"%d tests failed!", _fails];
	[OFStdOut writeFormat: @"%d tests failed!", _fails];

	sceKernelSleepThreadCB();
#elif defined(OF_NINTENDO_DS)
	[of_stdout writeString: @"Press start button to exit!"];
	[OFStdOut writeString: @"Press start button to exit!"];

	for (;;) {
		swiWaitForVBlank();
		scanKeys();
		if (keysDown() & KEY_START)
			[OFApplication terminateWithStatus: _fails];
	}
#elif defined(OF_NINTENDO_3DS)
	[of_stdout writeString: @"Press start button to exit!"];
	[OFStdOut writeString: @"Press start button to exit!"];

	for (;;) {
		hidScanInput();

		if (hidKeysDown() & KEY_START)
			[OFApplication terminateWithStatus: _fails];

Modified tests/terminal/TerminalTests.m from [8181966586] to [edc6e4e174].

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
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







-
+



-
-
+
+

-
-
+
+



-
-
+
+

-
-
+
+




-
-
-
+
+
+

-
-
+
+



-
+


-
+


-
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+


-
+


-
-
+
+


-
+

-
+

-
+

-
+

-
+

-
+


-
+


-
+




	    [OFColor maroon], [OFColor red], [OFColor purple],
	    [OFColor fuchsia], [OFColor green], [OFColor lime], [OFColor olive],
	    [OFColor yellow], [OFColor navy], [OFColor blue], [OFColor teal],
	    [OFColor aqua], nil];
	size_t i;
	OFEnumerator OF_GENERIC(OFColor *) *reverseEnumerator;

	[of_stdout writeFormat: @"%dx%d\n", of_stdout.columns, of_stdout.rows];
	[OFStdOut writeFormat: @"%dx%d\n", OFStdOut.columns, OFStdOut.rows];

	i = 0;
	for (OFColor *color in colors) {
		[of_stdout setForegroundColor: color];
		[of_stdout writeFormat: @"%zx", i++];
		[OFStdOut setForegroundColor: color];
		[OFStdOut writeFormat: @"%zx", i++];
	}
	[of_stdout reset];
	[of_stdout writeLine: @"R"];
	[OFStdOut reset];
	[OFStdOut writeLine: @"R"];

	i = 0;
	for (OFColor *color in colors) {
		[of_stdout setBackgroundColor: color];
		[of_stdout writeFormat: @"%zx", i++];
		[OFStdOut setBackgroundColor: color];
		[OFStdOut writeFormat: @"%zx", i++];
	}
	[of_stdout reset];
	[of_stdout writeLine: @"R"];
	[OFStdOut reset];
	[OFStdOut writeLine: @"R"];

	i = 0;
	reverseEnumerator = [colors.reversedArray objectEnumerator];
	for (OFColor *color in colors) {
		[of_stdout setForegroundColor: color];
		[of_stdout setBackgroundColor: [reverseEnumerator nextObject]];
		[of_stdout writeFormat: @"%zx", i++];
		[OFStdOut setForegroundColor: color];
		[OFStdOut setBackgroundColor: [reverseEnumerator nextObject]];
		[OFStdOut writeFormat: @"%zx", i++];
	}
	[of_stdout reset];
	[of_stdout writeLine: @"R"];
	[OFStdOut reset];
	[OFStdOut writeLine: @"R"];

	for (i = 0; i < colors.count * 2; i++) {
		if (i % 2)
			[of_stdout setBackgroundColor: [colors objectAtIndex:
			[OFStdOut setBackgroundColor: [colors objectAtIndex:
			    ((i / 2) + 2) % colors.count]];
		else
			[of_stdout setForegroundColor:
			[OFStdOut setForegroundColor:
			    [colors objectAtIndex: i / 2]];

		[of_stdout writeFormat: @"%zx", i / 2];
		[OFStdOut writeFormat: @"%zx", i / 2];
	}
	[of_stdout reset];
	[of_stdout writeLine: @"R"];
	[OFStdOut reset];
	[OFStdOut writeLine: @"R"];

	[of_stdout writeLine: @"Press return"];
	[of_stdin readLine];
	[OFStdOut writeLine: @"Press return"];
	[OFStdIn readLine];

	[of_stdout setBackgroundColor: [OFColor green]];
	[of_stdout writeString: @"Hello!"];
	[OFStdOut setBackgroundColor: [OFColor green]];
	[OFStdOut writeString: @"Hello!"];
	[OFThread sleepForTimeInterval: 2];
	[of_stdout eraseLine];
	[of_stdout writeString: @"World!"];
	[OFStdOut eraseLine];
	[OFStdOut writeString: @"World!"];
	[OFThread sleepForTimeInterval: 2];

	[of_stdout clear];
	[OFStdOut clear];
	[OFThread sleepForTimeInterval: 2];

	[of_stdout setCursorPosition: OFPointMake(5, 3)];
	[of_stdout writeString: @"Text at (5, 3)"];
	[OFStdOut setCursorPosition: OFPointMake(5, 3)];
	[OFStdOut writeString: @"Text at (5, 3)"];
	[OFThread sleepForTimeInterval: 2];

	[of_stdout setRelativeCursorPosition: OFPointMake(-2, 0)];
	[OFStdOut setRelativeCursorPosition: OFPointMake(-2, 0)];
	[OFThread sleepForTimeInterval: 2];
	[of_stdout setRelativeCursorPosition: OFPointMake(2, 0)];
	[OFStdOut setRelativeCursorPosition: OFPointMake(2, 0)];
	[OFThread sleepForTimeInterval: 2];
	[of_stdout setRelativeCursorPosition: OFPointMake(0, -2)];
	[OFStdOut setRelativeCursorPosition: OFPointMake(0, -2)];
	[OFThread sleepForTimeInterval: 2];
	[of_stdout setRelativeCursorPosition: OFPointMake(0, 2)];
	[OFStdOut setRelativeCursorPosition: OFPointMake(0, 2)];
	[OFThread sleepForTimeInterval: 2];
	[of_stdout setRelativeCursorPosition: OFPointMake(1, 1)];
	[OFStdOut setRelativeCursorPosition: OFPointMake(1, 1)];
	[OFThread sleepForTimeInterval: 2];
	[of_stdout setRelativeCursorPosition: OFPointMake(-1, -1)];
	[OFStdOut setRelativeCursorPosition: OFPointMake(-1, -1)];
	[OFThread sleepForTimeInterval: 2];

	[of_stdout setCursorColumn: 2];
	[OFStdOut setCursorColumn: 2];
	[OFThread sleepForTimeInterval: 2];

	[of_stdout reset];
	[OFStdOut reset];

	[OFApplication terminate];
}
@end

Modified utils/ofarc/GZIPArchive.m from [cd709fb905] to [5f3f952774].

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
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







-
+










-
+










-
+







	[_stream release];

	[super dealloc];
}

- (void)listFiles
{
	[of_stderr writeLine: OF_LOCALIZED(@"cannot_list_gz",
	[OFStdErr writeLine: OF_LOCALIZED(@"cannot_list_gz",
	    @"Cannot list files of a .gz archive!")];
	app->_exitStatus = 1;
}

- (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFString *fileName;
	OFFile *output;

	if (files.count != 0) {
		[of_stderr writeLine:
		[OFStdErr writeLine:
		    OF_LOCALIZED(@"cannot_extract_specific_file_from_gz",
		    @"Cannot extract a specific file of a .gz archive!")];
		app->_exitStatus = 1;
		return;
	}

	fileName = app->_archivePath.lastPathComponent
	    .stringByDeletingPathExtension;

	if (app->_outputLevel >= 0)
		[of_stdout writeString: OF_LOCALIZED(@"extracting_file",
		[OFStdOut writeString: OF_LOCALIZED(@"extracting_file",
		    @"Extracting %[file]...",
		    @"file", fileName)];

	if (![app shouldExtractFile: fileName outFileName: fileName])
		return;

	output = [OFFile fileWithPath: fileName mode: @"w"];
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
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







-
-
+
+











-
+








-
+









		}
	}

	[output close];
	setModificationDate(fileName, _stream);

	if (app->_outputLevel >= 0) {
		[of_stdout writeString: @"\r"];
		[of_stdout writeLine: OF_LOCALIZED(@"extracting_file_done",
		[OFStdOut writeString: @"\r"];
		[OFStdOut writeLine: OF_LOCALIZED(@"extracting_file_done",
		    @"Extracting %[file]... done",
		    @"file", fileName)];
	}
}

- (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFString *fileName = app->_archivePath.lastPathComponent
	    .stringByDeletingPathExtension;

	if (files.count > 0) {
		[of_stderr writeLine: OF_LOCALIZED(
		[OFStdErr writeLine: OF_LOCALIZED(
		    @"cannot_print_specific_file_from_gz",
		    @"Cannot print a specific file of a .gz archive!")];
		app->_exitStatus = 1;
		return;
	}

	while (!_stream.atEndOfStream) {
		ssize_t length = [app copyBlockFromStream: _stream
						 toStream: of_stdout
						 toStream: OFStdOut
						 fileName: fileName];

		if (length < 0) {
			app->_exitStatus = 1;
			return;
		}
	}
}
@end

Modified utils/ofarc/LHAArchive.m from [228be0ebf1] to [051184aa1d].

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
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
252
253
254
255
256
257
258
259
260


261
262
263
264
265
266
267
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
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
252
253
254
255
256
257
258


259
260
261
262
263
264
265
266
267







-
+











-
-
+
+









-
-
+
+









-
-
+
+



-
-
+
+


-
-
+
+








-
-
+
+




-
-
+
+




-
-
+
+




-
-
+
+





-
-
+
+










-
-
+
+









-
-
+
+










-
-
+
+










-
-
+
+







- (void)listFiles
{
	OFLHAArchiveEntry *entry;

	while ((entry = [_archive nextEntry]) != nil) {
		void *pool = objc_autoreleasePoolPush();

		[of_stdout writeLine: entry.fileName];
		[OFStdOut writeLine: entry.fileName];

		if (app->_outputLevel >= 1) {
			OFString *date = [entry.date
			    localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];
			OFString *compressedSize = [OFString stringWithFormat:
			    @"%" PRIu32, entry.compressedSize];
			OFString *uncompressedSize = [OFString stringWithFormat:
			    @"%" PRIu32, entry.uncompressedSize];
			OFString *CRC16 = [OFString stringWithFormat:
			    @"%04" PRIX16, entry.CRC16];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    @"["
			    @"    'Compressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", compressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_uncompressed_size",
			    @"["
			    @"    'Uncompressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", uncompressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_compression_method",
			    @"Compression method: %[method]",
			    @"method", entry.compressionMethod)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_crc16",
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(@"list_crc16",
			    @"CRC16: %[crc16]",
			    @"crc16", CRC16)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_date",
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(@"list_date",
			    @"Date: %[date]",
			    @"date", date)];

			if (entry.mode != nil) {
				OFString *modeString = [OFString
				    stringWithFormat:
				    @"%ho", entry.mode.unsignedShortValue];

				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(@"list_mode",
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(@"list_mode",
				    @"Mode: %[mode]",
				    @"mode", modeString)];
			}
			if (entry.UID != nil) {
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(@"list_uid",
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(@"list_uid",
				    @"UID: %[uid]",
				    @"uid", entry.UID)];
			}
			if (entry.GID != nil) {
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(@"list_gid",
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(@"list_gid",
				    @"GID: %[gid]",
				    @"gid", entry.GID)];
			}
			if (entry.owner != nil) {
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_owner",
				    @"Owner: %[owner]",
				    @"owner", entry.owner)];
			}
			if (entry.group != nil) {
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_group",
				    @"Group: %[group]",
				    @"group", entry.group)];
			}

			if (app->_outputLevel >= 2) {
				OFString *headerLevel = [OFString
				    stringWithFormat: @"%" PRIu8,
						      entry.headerLevel];

				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_header_level",
				    @"Header level: %[level]",
				    @"level", headerLevel)];

				if (entry.operatingSystemIdentifier != '\0') {
					OFString *OSID =
					    [OFString stringWithFormat: @"%c",
					    entry.operatingSystemIdentifier];

					[of_stdout writeString: @"\t"];
					[of_stdout writeLine: OF_LOCALIZED(
					[OFStdOut writeString: @"\t"];
					[OFStdOut writeLine: OF_LOCALIZED(
					    @"list_osid",
					    @"Operating system identifier: "
					    "%[osid]",
					    @"osid", OSID)];
				}

				if (entry.modificationDate != nil) {
					OFString *modificationDate =
					    entry.modificationDate.description;

					[of_stdout writeString: @"\t"];
					[of_stdout writeLine: OF_LOCALIZED(
					[OFStdOut writeString: @"\t"];
					[OFStdOut writeLine: OF_LOCALIZED(
					    @"list_modification_date",
					    @"Modification date: %[date]",
					    @"date", modificationDate)];
				}
			}

			if (app->_outputLevel >= 3) {
				OFString *extensions =
				    indent(entry.extensions.description);

				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_extensions",
				    @"Extensions: %[extensions]",
				    @"extensions", extensions)];
			}
		}

		objc_autoreleasePoolPop(pool);
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
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







-
+









-
+










-
-
+
+







		if (!all && ![files containsObject: fileName])
			continue;

		[missing removeObject: fileName];

		outFileName = [app safeLocalPathForPath: fileName];
		if (outFileName == nil) {
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"refusing_to_extract_file",
			    @"Refusing to extract %[file]!",
			    @"file", fileName)];

			app->_exitStatus = 1;
			goto outer_loop_end;
		}

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"extracting_file",
			[OFStdOut writeString: OF_LOCALIZED(@"extracting_file",
			    @"Extracting %[file]...",
			    @"file", fileName)];

		if ([fileName hasSuffix: @"/"]) {
			[fileManager createDirectoryAtPath: outFileName
					     createParents: true];
			setPermissions(outFileName, entry);
			setModificationDate(outFileName, entry);

			if (app->_outputLevel >= 0) {
				[of_stdout writeString: @"\r"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\r"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"extracting_file_done",
				    @"Extracting %[file]... done",
				    @"file", fileName)];
			}

			goto outer_loop_end;
		}
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
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
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
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
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
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







-
-
+
+











-
-
+
+











-
+














-
+


















-
+
















-
+











-
+













-
+







			if (app->_outputLevel >= 0 && percent != newPercent) {
				OFString *percentString;

				percent = newPercent;
				percentString = [OFString stringWithFormat:
				    @"%3u", percent];

				[of_stdout writeString: @"\r"];
				[of_stdout writeString: OF_LOCALIZED(
				[OFStdOut writeString: @"\r"];
				[OFStdOut writeString: OF_LOCALIZED(
				    @"extracting_file_percent",
				    @"Extracting %[file]... %[percent]%",
				    @"file", fileName,
				    @"percent", percentString)];
			}
		}

		[output close];
		setModificationDate(outFileName, entry);

		if (app->_outputLevel >= 0) {
			[of_stdout writeString: @"\r"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\r"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"extracting_file_done",
			    @"Extracting %[file]... done",
			    @"file", fileName)];
		}

outer_loop_end:
		objc_autoreleasePoolPop(pool);
	}

	if (missing.count > 0) {
		for (OFString *file in missing)
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"file_not_in_archive",
			    @"File %[file] is not in the archive!",
			    @"file", file)];

		app->_exitStatus = 1;
	}
}

- (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files_
{
	OFMutableSet *files;
	OFLHAArchiveEntry *entry;

	if (files_.count < 1) {
		[of_stderr writeLine: OF_LOCALIZED(@"print_no_file_specified",
		[OFStdErr writeLine: OF_LOCALIZED(@"print_no_file_specified",
		    @"Need one or more files to print!")];
		app->_exitStatus = 1;
		return;
	}

	files = [OFMutableSet setWithArray: files_];

	while ((entry = [_archive nextEntry]) != nil) {
		OFString *fileName = entry.fileName;
		OFStream *stream;

		if (![files containsObject: fileName])
			continue;

		stream = [_archive streamForReadingCurrentEntry];

		while (!stream.atEndOfStream) {
			ssize_t length = [app copyBlockFromStream: stream
							 toStream: of_stdout
							 toStream: OFStdOut
							 fileName: fileName];

			if (length < 0) {
				app->_exitStatus = 1;
				return;
			}
		}

		[files removeObject: fileName];
		[stream close];

		if (files.count == 0)
			break;
	}

	for (OFString *file in files) {
		[of_stderr writeLine: OF_LOCALIZED(@"file_not_in_archive",
		[OFStdErr writeLine: OF_LOCALIZED(@"file_not_in_archive",
		    @"File %[file] is not in the archive!",
		    @"file", file)];
		app->_exitStatus = 1;
	}
}

- (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFFileManager *fileManager = [OFFileManager defaultManager];

	if (files.count < 1) {
		[of_stderr writeLine: OF_LOCALIZED(@"add_no_file_specified",
		[OFStdErr writeLine: OF_LOCALIZED(@"add_no_file_specified",
		    @"Need one or more files to add!")];
		app->_exitStatus = 1;
		return;
	}

	for (OFString *fileName in files) {
		void *pool = objc_autoreleasePoolPush();
		OFFileAttributes attributes;
		OFFileAttributeType type;
		OFMutableLHAArchiveEntry *entry;
		OFStream *output;

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"adding_file",
			[OFStdOut writeString: OF_LOCALIZED(@"adding_file",
			    @"Adding %[file]...",
			    @"file", fileName)];

		attributes = [fileManager attributesOfItemAtPath: fileName];
		type = attributes.fileType;
		entry = [OFMutableLHAArchiveEntry entryWithFileName: fileName];

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
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







-
-
+
+









-
-
+
+







				    percent != newPercent) {
					OFString *percentString;

					percent = newPercent;
					percentString = [OFString
					    stringWithFormat: @"%3u", percent];

					[of_stdout writeString: @"\r"];
					[of_stdout writeString: OF_LOCALIZED(
					[OFStdOut writeString: @"\r"];
					[OFStdOut writeString: OF_LOCALIZED(
					    @"adding_file_percent",
					    @"Adding %[file]... %[percent]%",
					    @"file", fileName,
					    @"percent", percentString)];
				}
			}
		}

		if (app->_outputLevel >= 0) {
			[of_stdout writeString: @"\r"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\r"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"adding_file_done",
			    @"Adding %[file]... done",
			    @"file", fileName)];
		}

		[output close];

Modified utils/ofarc/OFArc.m from [cd177e69a6] to [6f8d6d31cd].

85
86
87
88
89
90
91
92

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

92
93
94
95
96
97
98
99







-
+







    OFUnichar shortOption2, OFString *longOption2)
{
	OFString *shortOption1Str = [OFString stringWithFormat: @"%C",
								shortOption1];
	OFString *shortOption2Str = [OFString stringWithFormat: @"%C",
								shortOption2];

	[of_stderr writeLine: OF_LOCALIZED(@"2_options_mutually_exclusive",
	[OFStdErr writeLine: OF_LOCALIZED(@"2_options_mutually_exclusive",
	    @"Error: -%[shortopt1] / --%[longopt1] and "
	    @"-%[shortopt2] / --%[longopt2] "
	    @"are mutually exclusive!",
	    @"shortopt1", shortOption1Str,
	    @"longopt1", longOption1,
	    @"shortopt2", shortOption2Str,
	    @"longopt2", longOption2)];
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
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







-
+




















-
+







	OFString *shortOption3Str = [OFString stringWithFormat: @"%C",
								shortOption3];
	OFString *shortOption4Str = [OFString stringWithFormat: @"%C",
								shortOption4];
	OFString *shortOption5Str = [OFString stringWithFormat: @"%C",
								shortOption5];

	[of_stderr writeLine: OF_LOCALIZED(@"5_options_mutually_exclusive",
	[OFStdErr writeLine: OF_LOCALIZED(@"5_options_mutually_exclusive",
	    @"Error: -%[shortopt1] / --%[longopt1], "
	    @"-%[shortopt2] / --%[longopt2], -%[shortopt3] / --%[longopt3], "
	    @"-%[shortopt4] / --%[longopt4] and\n"
	    @"       -%[shortopt5] / --%[longopt5] are mutually exclusive!",
	    @"shortopt1", shortOption1Str,
	    @"longopt1", longOption1,
	    @"shortopt2", shortOption2Str,
	    @"longopt2", longOption2,
	    @"shortopt3", shortOption3Str,
	    @"longopt3", longOption3,
	    @"shortopt4", shortOption4Str,
	    @"longopt4", longOption4,
	    @"shortopt5", shortOption5Str,
	    @"longopt5", longOption5)];
	[OFApplication terminateWithStatus: 1];
}

static void
writingNotSupported(OFString *type)
{
	[of_stderr writeLine: OF_LOCALIZED(
	[OFStdErr writeLine: OF_LOCALIZED(
	    @"writing_not_supported",
	    @"Writing archives of type %[type] is not (yet) supported!",
	    @"type", type)];
}

@implementation OFArc
- (void)applicationDidFinishLaunching
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
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
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
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







-
+


-
+









-
+









-
+











-
+








-
+















-
+














-
+







				    'l', @"list",
				    'p', @"print",
				    'x', @"extract");

			mode = option;
			break;
		case 'h':
			help(of_stdout, true, 0);
			help(OFStdOut, true, 0);
			break;
		case '=':
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"option_takes_no_argument",
			    @"%[prog]: Option --%[opt] takes no argument",
			    @"prog", [OFApplication programName],
			    @"opt", optionsParser.lastLongOption)];

			[OFApplication terminateWithStatus: 1];
			break;
		case ':':
			if (optionsParser.lastLongOption != nil)
				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"long_option_requires_argument",
				    @"%[prog]: Option --%[opt] requires an "
				    @"argument",
				    @"prog", [OFApplication programName],
				    @"opt", optionsParser.lastLongOption)];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%C",
				    optionsParser.lastOption];
				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"option_requires_argument",
				    @"%[prog]: Option -%[opt] requires an "
				    @"argument",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
			break;
		case '?':
			if (optionsParser.lastLongOption != nil)
				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"unknown_long_option",
				    @"%[prog]: Unknown option: --%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", optionsParser.lastLongOption)];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%C",
				    optionsParser.lastOption];
				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"unknown_option",
				    @"%[prog]: Unknown option: -%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
			break;
		}
	}

	@try {
		if (encodingString != nil)
			encoding = OFStringEncodingParseName(encodingString);
	} @catch (OFInvalidArgumentException *e) {
		[of_stderr writeLine: OF_LOCALIZED(
		[OFStdErr writeLine: OF_LOCALIZED(
		    @"invalid_encoding",
		    @"%[prog]: Invalid encoding: %[encoding]",
		    @"prog", [OFApplication programName],
		    @"encoding", encodingString)];

		[OFApplication terminateWithStatus: 1];
	}

	remainingArguments = optionsParser.remainingArguments;

	switch (mode) {
	case 'a':
	case 'c':
		if (remainingArguments.count < 1)
			help(of_stderr, false, 1);
			help(OFStdErr, false, 1);

		files = [remainingArguments objectsInRange:
		    OFRangeMake(1, remainingArguments.count - 1)];

#ifdef OF_HAVE_SANDBOX
		if (![remainingArguments.firstObject isEqual: @"-"])
			[sandbox unveilPath: remainingArguments.firstObject
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371







-
+




















-
+







				   mode: mode
			       encoding: encoding];

		[archive addFiles: files];
		break;
	case 'l':
		if (remainingArguments.count != 1)
			help(of_stderr, false, 1);
			help(OFStdErr, false, 1);

#ifdef OF_HAVE_SANDBOX
		if (![remainingArguments.firstObject isEqual: @"-"])
			[sandbox unveilPath: remainingArguments.firstObject
				permissions: @"r"];

		sandbox.allowsUnveil = false;
		[OFApplication of_activateSandbox: sandbox];
#endif

		archive = [self
		    openArchiveWithPath: remainingArguments.firstObject
				   type: type
				   mode: mode
			       encoding: encoding];

		[archive listFiles];
		break;
	case 'p':
		if (remainingArguments.count < 1)
			help(of_stderr, false, 1);
			help(OFStdErr, false, 1);

#ifdef OF_HAVE_SANDBOX
		if (![remainingArguments.firstObject isEqual: @"-"])
			[sandbox unveilPath: remainingArguments.firstObject
				permissions: @"r"];

		sandbox.allowsUnveil = false;
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395







-
+







				   mode: mode
			       encoding: encoding];

		[archive printFiles: files];
		break;
	case 'x':
		if (remainingArguments.count < 1)
			help(of_stderr, false, 1);
			help(OFStdErr, false, 1);

		files = [remainingArguments objectsInRange:
		    OFRangeMake(1, remainingArguments.count - 1)];

#ifdef OF_HAVE_SANDBOX
		if (![remainingArguments.firstObject isEqual: @"-"])
			[sandbox unveilPath: remainingArguments.firstObject
428
429
430
431
432
433
434
435
436


437
438
439
440
441
442
443
444
445
446
447


448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
428
429
430
431
432
433
434


435
436
437
438
439
440
441
442
443
444
445


446
447
448
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464







-
-
+
+









-
-
+
+









-
+








		@try {
			[archive extractFiles: files];
		} @catch (OFCreateDirectoryFailedException *e) {
			OFString *error = [OFString
			    stringWithCString: strerror(e.errNo)
				     encoding: [OFLocale encoding]];
			[of_stderr writeString: @"\r"];
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeString: @"\r"];
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"failed_to_create_directory",
			    @"Failed to create directory %[dir]: %[error]",
			    @"dir", e.URL.fileSystemRepresentation,
			    @"error", error)];
			_exitStatus = 1;
		} @catch (OFOpenItemFailedException *e) {
			OFString *error = [OFString
			    stringWithCString: strerror(e.errNo)
				     encoding: [OFLocale encoding]];
			[of_stderr writeString: @"\r"];
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeString: @"\r"];
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"failed_to_open_file",
			    @"Failed to open file %[file]: %[error]",
			    @"file", e.path,
			    @"error", error)];
			_exitStatus = 1;
		}

		break;
	default:
		help(of_stderr, true, 1);
		help(OFStdErr, true, 1);
		break;
	}

	[OFApplication terminateWithStatus: _exitStatus];
}

- (id <Archive>)openArchiveWithPath: (OFString *)path
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
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







-
+




-
+











-
-
+
+







		@throw [OFInvalidArgumentException exception];
	}

	if ([path isEqual: @"-"]) {
		switch (mode) {
		case 'a':
		case 'c':
			file = of_stdout;
			file = OFStdOut;
			break;
		case 'l':
		case 'p':
		case 'x':
			file = of_stdin;
			file = OFStdIn;
			break;
		default:
			@throw [OFInvalidArgumentException exception];
		}
	} else {
		@try {
			file = [OFFile fileWithPath: path mode: fileModeString];
		} @catch (OFOpenItemFailedException *e) {
			OFString *error = [OFString
			    stringWithCString: strerror(e.errNo)
				     encoding: [OFLocale encoding]];
			[of_stderr writeString: @"\r"];
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeString: @"\r"];
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"failed_to_open_file",
			    @"Failed to open file %[file]: %[error]",
			    @"file", e.path,
			    @"error", error)];
			[OFApplication terminateWithStatus: 1];
		}
	}
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
593
594

595
596
597
598
599
600

601
602
603
604
605
606
607
560
561
562
563
564
565
566

567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
592
593

594
595
596
597
598
599

600
601
602
603
604
605
606
607







-
+

















-
+








-
+





-
+







							   mode: modeString
						       encoding: encoding];
		} else if ([type isEqual: @"zip"])
			archive = [ZIPArchive archiveWithStream: file
							   mode: modeString
						       encoding: encoding];
		else {
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"unknown_archive_type",
			    @"Unknown archive type: %[type]",
			    @"type", type)];
			goto error;
		}
	} @catch (OFNotImplementedException *e) {
		if ((mode == 'a' || mode == 'c') && sel_isEqual(e.selector,
		    @selector(initWithStream:mode:))) {
			writingNotSupported(type);
			goto error;
		}

		@throw e;
	} @catch (OFReadFailedException *e) {
		OFString *error = [OFString
		    stringWithCString: strerror(e.errNo)
			     encoding: [OFLocale encoding]];
		[of_stderr writeLine: OF_LOCALIZED(@"failed_to_read_file",
		[OFStdErr writeLine: OF_LOCALIZED(@"failed_to_read_file",
		    @"Failed to read file %[file]: %[error]",
		    @"file", path,
		    @"error", error)];
		goto error;
	} @catch (OFSeekFailedException *e) {
		OFString *error = [OFString
		    stringWithCString: strerror(e.errNo)
			     encoding: [OFLocale encoding]];
		[of_stderr writeLine: OF_LOCALIZED(@"failed_to_seek_in_file",
		[OFStdErr writeLine: OF_LOCALIZED(@"failed_to_seek_in_file",
		    @"Failed to seek in file %[file]: %[error]",
		    @"file", path,
		    @"error", error)];
		goto error;
	} @catch (OFInvalidFormatException *e) {
		[of_stderr writeLine: OF_LOCALIZED(
		[OFStdErr writeLine: OF_LOCALIZED(
		    @"file_is_not_a_valid_archive",
		    @"File %[file] is not a valid archive!",
		    @"file", path)];
		goto error;
	}

	if ((mode == 'a' || mode == 'c') &&
627
628
629
630
631
632
633
634
635


636
637
638
639
640
641
642
643


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

676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696


697
698
699
700
701
702
703
704
705
706
707
708
709
710


711
712
713
714
715
716
717
627
628
629
630
631
632
633


634
635
636
637
638
639
640
641


642
643
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
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694


695
696
697
698
699
700
701
702
703
704
705
706
707
708


709
710
711
712
713
714
715
716
717







-
-
+
+






-
-
+
+


-
+

-
+


-
+















-
+







-
+



















-
-
+
+












-
-
+
+








	if (_overwrite == 1 ||
	    ![[OFFileManager defaultManager] fileExistsAtPath: outFileName])
		return true;

	if (_overwrite == -1) {
		if (_outputLevel >= 0) {
			[of_stdout writeString: @" "];
			[of_stdout writeLine:
			[OFStdOut writeString: @" "];
			[OFStdOut writeLine:
			    OF_LOCALIZED(@"file_skipped", @"skipped")];
		}
		return false;
	}

	do {
		[of_stderr writeString: @"\r"];
		[of_stderr writeString: OF_LOCALIZED(@"ask_overwrite",
		[OFStdErr writeString: @"\r"];
		[OFStdErr writeString: OF_LOCALIZED(@"ask_overwrite",
		    @"Overwrite %[file]? [ynAN?]",
		    @"file", fileName)];
		[of_stderr writeString: @" "];
		[OFStdErr writeString: @" "];

		line = [of_stdin readLine];
		line = [OFStdIn readLine];

		if ([line isEqual: @"?"])
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"ask_overwrite_help",
			    @" y: yes\n"
			    @" n: no\n"
			    @" A: always\n"
			    @" N: never")];
	} while (![line isEqual: @"y"] && ![line isEqual: @"n"] &&
	    ![line isEqual: @"N"] && ![line isEqual: @"A"]);

	if ([line isEqual: @"A"])
		_overwrite = 1;
	else if ([line isEqual: @"N"])
		_overwrite = -1;

	if ([line isEqual: @"n"] || [line isEqual: @"N"]) {
		if (_outputLevel >= 0)
			[of_stdout writeLine: OF_LOCALIZED(@"skipping_file",
			[OFStdOut writeLine: OF_LOCALIZED(@"skipping_file",
			    @"Skipping %[file]...",
			    @"file", fileName)];

		return false;
	}

	if (_outputLevel >= 0)
		[of_stdout writeString: OF_LOCALIZED(@"extracting_file",
		[OFStdOut writeString: OF_LOCALIZED(@"extracting_file",
		    @"Extracting %[file]...",
		    @"file", fileName)];

	return true;
}

- (ssize_t)copyBlockFromStream: (OFStream *)input
		      toStream: (OFStream *)output
		      fileName: (OFString *)fileName
{
	char buffer[BUFFER_SIZE];
	size_t length;

	@try {
		length = [input readIntoBuffer: buffer length: BUFFER_SIZE];
	} @catch (OFReadFailedException *e) {
		OFString *error = [OFString
		    stringWithCString: strerror(e.errNo)
			     encoding: [OFLocale encoding]];
		[of_stdout writeString: @"\r"];
		[of_stderr writeLine: OF_LOCALIZED(@"failed_to_read_file",
		[OFStdOut writeString: @"\r"];
		[OFStdErr writeLine: OF_LOCALIZED(@"failed_to_read_file",
		    @"Failed to read file %[file]: %[error]",
		    @"file", fileName,
		    @"error", error)];
		return -1;
	}

	@try {
		[output writeBuffer: buffer length: length];
	} @catch (OFWriteFailedException *e) {
		OFString *error = [OFString
		    stringWithCString: strerror(e.errNo)
			     encoding: [OFLocale encoding]];
		[of_stdout writeString: @"\r"];
		[of_stderr writeLine: OF_LOCALIZED(@"failed_to_write_file",
		[OFStdOut writeString: @"\r"];
		[OFStdErr writeLine: OF_LOCALIZED(@"failed_to_write_file",
		    @"Failed to write file %[file]: %[error]",
		    @"file", fileName,
		    @"error", error)];
		return -1;
	}

	return length;

Modified utils/ofarc/TarArchive.m from [661f4e2e9e] to [a19def56d5].

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
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
252
253

254
255
256
257
258

259
260
261
262
263
264
265
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
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
252

253
254
255
256
257

258
259
260
261
262
263
264
265







-
+













-
-
+
+








-
-
+
+


-
-
+
+


-
-
+
+




-
-
+
+





-
-
+
+





-
-
+
+






-
+



-
+




-
+


-
-
+
+





-
+


-
-
+
+










-
+


-
-
+
+



-
-
+
+











-
+


-
-
+
+



-
-
+
+






-
+




-
+




-
+




-
+







- (void)listFiles
{
	OFTarArchiveEntry *entry;

	while ((entry = [_archive nextEntry]) != nil) {
		void *pool = objc_autoreleasePoolPush();

		[of_stdout writeLine: entry.fileName];
		[OFStdOut writeLine: entry.fileName];

		if (app->_outputLevel >= 1) {
			OFString *date = [entry.modificationDate
			    localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];
			OFString *size = [OFString stringWithFormat:
			    @"%" PRIu64, entry.size];
			OFString *mode = [OFString stringWithFormat:
			    @"%06o", entry.mode];
			OFString *UID = [OFString stringWithFormat:
			    @"%u", entry.UID];
			OFString *GID = [OFString stringWithFormat:
			    @"%u", entry.GID];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_size",
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(@"list_size",
			    @"["
			    @"    'Size: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", size)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_mode",
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(@"list_mode",
			    @"Mode: %[mode]",
			    @"mode", mode)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_uid",
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(@"list_uid",
			    @"UID: %[uid]",
			    @"uid", UID)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_gid",
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(@"list_gid",
			    @"GID: %[gid]",
			    @"gid", GID)];

			if (entry.owner != nil) {
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_owner",
				    @"Owner: %[owner]",
				    @"owner", entry.owner)];
			}
			if (entry.group != nil) {
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_group",
				    @"Group: %[group]",
				    @"group", entry.group)];
			}

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_modification_date",
			    @"Modification date: %[date]",
			    @"date", date)];
		}

		if (app->_outputLevel >= 2) {
			[of_stdout writeString: @"\t"];
			[OFStdOut writeString: @"\t"];

			switch (entry.type) {
			case OFTarArchiveEntryTypeFile:
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_type_normal",
				    @"Type: Normal file")];
				break;
			case OFTarArchiveEntryTypeLink:
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_type_hardlink",
				    @"Type: Hard link")];
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_link_target",
				    @"Target file name: %[target]",
				    @"target", entry.targetFileName)];
				break;
			case OFTarArchiveEntryTypeSymlink:
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_type_symlink",
				    @"Type: Symbolic link")];
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_link_target",
				    @"Target file name: %[target]",
				    @"target", entry.targetFileName)];
				break;
			case OFTarArchiveEntryTypeCharacterDevice: {
				OFString *majorString = [OFString
				    stringWithFormat: @"%d", entry.deviceMajor];
				OFString *minorString = [OFString
				    stringWithFormat: @"%d", entry.deviceMinor];

				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_type_character_device",
				    @"Type: Character device")];
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_device_major",
				    @"Device major: %[major]",
				    @"major", majorString)];
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_device_minor",
				    @"Device minor: %[minor]",
				    @"minor", minorString)];
				break;
			}
			case OFTarArchiveEntryTypeBlockDevice: {
				OFString *majorString = [OFString
				    stringWithFormat: @"%d", entry.deviceMajor];
				OFString *minorString = [OFString
				    stringWithFormat: @"%d", entry.deviceMinor];

				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_type_block_device",
				    @"Type: Block device")];
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_device_major",
				    @"Device major: %[major]",
				    @"major", majorString)];
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_device_minor",
				    @"Device minor: %[minor]",
				    @"minor", minorString)];
				break;
			}
			case OFTarArchiveEntryTypeDirectory:
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_type_directory",
				    @"Type: Directory")];
				break;
			case OFTarArchiveEntryTypeFIFO:
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_type_fifo",
				    @"Type: FIFO")];
				break;
			case OFTarArchiveEntryTypeContiguousFile:
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_type_contiguous_file",
				    @"Type: Contiguous file")];
				break;
			default:
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_type_unknown",
				    @"Type: Unknown")];
				break;
			}
		}

		objc_autoreleasePoolPop(pool);
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
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







-
+










-
+









-
+












-
-
+
+








		if (!all && ![files containsObject: fileName])
			continue;

		if (type != OFTarArchiveEntryTypeFile &&
		    type != OFTarArchiveEntryTypeDirectory) {
			if (app->_outputLevel >= 0)
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"skipping_file",
				    @"Skipping %[file]...",
				    @"file", fileName)];
			continue;
		}

		[missing removeObject: fileName];

		outFileName = [app safeLocalPathForPath: fileName];
		if (outFileName == nil) {
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"refusing_to_extract_file",
			    @"Refusing to extract %[file]!",
			    @"file", fileName)];

			app->_exitStatus = 1;
			goto outer_loop_end;
		}

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"extracting_file",
			[OFStdOut writeString: OF_LOCALIZED(@"extracting_file",
			    @"Extracting %[file]...",
			    @"file", fileName)];

		if (type == OFTarArchiveEntryTypeDirectory ||
		    (type == OFTarArchiveEntryTypeFile &&
		    [fileName hasSuffix: @"/"])) {
			[fileManager createDirectoryAtPath: outFileName
					     createParents: true];
			setPermissions(outFileName, entry);
			setModificationDate(outFileName, entry);

			if (app->_outputLevel >= 0) {
				[of_stdout writeString: @"\r"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\r"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"extracting_file_done",
				    @"Extracting %[file]... done",
				    @"file", fileName)];
			}

			goto outer_loop_end;
		}
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
428
429
430

431
432
433
434
435
436
437
438
439
440
441
442
443
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
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
428
429

430
431
432
433
434
435
436
437
438
439
440
441
442
443
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







-
-
+
+











-
-
+
+











-
+














-
+


















-
+
















-
+











-
+













-
+







			if (app->_outputLevel >= 0 && percent != newPercent) {
				OFString *percentString;

				percent = newPercent;
				percentString = [OFString stringWithFormat:
				    @"%3u", percent];

				[of_stdout writeString: @"\r"];
				[of_stdout writeString: OF_LOCALIZED(
				[OFStdOut writeString: @"\r"];
				[OFStdOut writeString: OF_LOCALIZED(
				    @"extracting_file_percent",
				    @"Extracting %[file]... %[percent]%",
				    @"file", fileName,
				    @"percent", percentString)];
			}
		}

		[output close];
		setModificationDate(outFileName, entry);

		if (app->_outputLevel >= 0) {
			[of_stdout writeString: @"\r"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\r"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"extracting_file_done",
			    @"Extracting %[file]... done",
			    @"file", fileName)];
		}

outer_loop_end:
		objc_autoreleasePoolPop(pool);
	}

	if (missing.count > 0) {
		for (OFString *file in missing)
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"file_not_in_archive",
			    @"File %[file] is not in the archive!",
			    @"file", file)];

		app->_exitStatus = 1;
	}
}

- (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files_
{
	OFMutableSet *files;
	OFTarArchiveEntry *entry;

	if (files_.count < 1) {
		[of_stderr writeLine: OF_LOCALIZED(@"print_no_file_specified",
		[OFStdErr writeLine: OF_LOCALIZED(@"print_no_file_specified",
		    @"Need one or more files to print!")];
		app->_exitStatus = 1;
		return;
	}

	files = [OFMutableSet setWithArray: files_];

	while ((entry = [_archive nextEntry]) != nil) {
		OFString *fileName = entry.fileName;
		OFStream *stream;

		if (![files containsObject: fileName])
			continue;

		stream = [_archive streamForReadingCurrentEntry];

		while (!stream.atEndOfStream) {
			ssize_t length = [app copyBlockFromStream: stream
							 toStream: of_stdout
							 toStream: OFStdOut
							 fileName: fileName];

			if (length < 0) {
				app->_exitStatus = 1;
				return;
			}
		}

		[files removeObject: fileName];
		[stream close];

		if (files.count == 0)
			break;
	}

	for (OFString *file in files) {
		[of_stderr writeLine: OF_LOCALIZED(@"file_not_in_archive",
		[OFStdErr writeLine: OF_LOCALIZED(@"file_not_in_archive",
		    @"File %[file] is not in the archive!",
		    @"file", file)];
		app->_exitStatus = 1;
	}
}

- (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFFileManager *fileManager = [OFFileManager defaultManager];

	if (files.count < 1) {
		[of_stderr writeLine: OF_LOCALIZED(@"add_no_file_specified",
		[OFStdErr writeLine: OF_LOCALIZED(@"add_no_file_specified",
		    @"Need one or more files to add!")];
		app->_exitStatus = 1;
		return;
	}

	for (OFString *fileName in files) {
		void *pool = objc_autoreleasePoolPush();
		OFFileAttributes attributes;
		OFFileAttributeType type;
		OFMutableTarArchiveEntry *entry;
		OFStream *output;

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"adding_file",
			[OFStdOut writeString: OF_LOCALIZED(@"adding_file",
			    @"Adding %[file]...",
			    @"file", fileName)];

		attributes = [fileManager attributesOfItemAtPath: fileName];
		type = attributes.fileType;
		entry = [OFMutableTarArchiveEntry entryWithFileName: fileName];

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
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







-
-
+
+









-
-
+
+







				    percent != newPercent) {
					OFString *percentString;

					percent = newPercent;
					percentString = [OFString
					    stringWithFormat: @"%3u", percent];

					[of_stdout writeString: @"\r"];
					[of_stdout writeString: OF_LOCALIZED(
					[OFStdOut writeString: @"\r"];
					[OFStdOut writeString: OF_LOCALIZED(
					    @"adding_file_percent",
					    @"Adding %[file]... %[percent]%",
					    @"file", fileName,
					    @"percent", percentString)];
				}
			}
		}

		if (app->_outputLevel >= 0) {
			[of_stdout writeString: @"\r"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\r"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"adding_file_done",
			    @"Adding %[file]... done",
			    @"file", fileName)];
		}

		[output close];

Modified utils/ofarc/ZIPArchive.m from [2b6d39166d] to [6b1b9a0f7a].

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
222
223
224
225
226
227


228
229
230
231
232
233
234
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
222
223
224
225


226
227
228
229
230
231
232
233
234







-
+
















-
-
+
+









-
-
+
+









-
-
+
+



-
-
+
+


-
-
+
+









-
-
+
+





-
-
+
+











-
-
+
+










-
-
+
+





-
-
+
+








-
-
+
+







}

- (void)listFiles
{
	for (OFZIPArchiveEntry *entry in _archive.entries) {
		void *pool = objc_autoreleasePoolPush();

		[of_stdout writeLine: entry.fileName];
		[OFStdOut writeLine: entry.fileName];

		if (app->_outputLevel >= 1) {
			OFString *compressedSize = [OFString
			    stringWithFormat: @"%" PRIu64,
					      entry.compressedSize];
			OFString *uncompressedSize = [OFString
			    stringWithFormat: @"%" PRIu64,
					      entry.uncompressedSize];
			OFString *compressionMethod =
			    OFZIPArchiveEntryCompressionMethodName(
			    entry.compressionMethod);
			OFString *CRC32 = [OFString
			    stringWithFormat: @"%08" PRIX32, entry.CRC32];
			OFString *modificationDate = [entry.modificationDate
			    localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    @"["
			    @"    'Compressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", compressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_uncompressed_size",
			    @"["
			    @"    'Uncompressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", uncompressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_compression_method",
			    @"Compression method: %[method]",
			    @"method", compressionMethod)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_crc32",
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(@"list_crc32",
			    @"CRC32: %[crc32]",
			    @"crc32", CRC32)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_modification_date",
			    @"Modification date: %[date]",
			    @"date", modificationDate)];

			if (app->_outputLevel >= 2) {
				uint16_t versionMadeBy = entry.versionMadeBy;
				OFZIPArchiveEntryAttributeCompatibility UNIX =
				    OFZIPArchiveEntryAttributeCompatibilityUNIX;

				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_version_made_by",
				    @"Version made by: %[version]",
				    @"version",
				    OFZIPArchiveEntryVersionToString(
				    versionMadeBy))];
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_min_version_needed",
				    @"Minimum version needed: %[version]",
				    @"version",
				    OFZIPArchiveEntryVersionToString(
				    entry.minVersionNeeded))];

				if ((versionMadeBy >> 8) == UNIX) {
					uint32_t mode = entry
					    .versionSpecificAttributes >> 16;
					OFString *modeString = [OFString
					    stringWithFormat: @"%06o", mode];
					[of_stdout writeString: @"\t"];
					[of_stdout writeLine: OF_LOCALIZED(
					[OFStdOut writeString: @"\t"];
					[OFStdOut writeLine: OF_LOCALIZED(
					    @"list_mode",
					    @"Mode: %[mode]",
					    @"mode", modeString)];
				}
			}

			if (app->_outputLevel >= 3) {
				OFString *GPBF = [OFString stringWithFormat:
				    @"%04" PRIx16, entry.generalPurposeBitFlag];

				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_general_purpose_bit_flag",
				    @"General purpose bit flag: %[gpbf]",
				    @"gpbf", GPBF)];

				if (entry.extraField != nil) {
					[of_stdout writeString: @"\t"];
					[of_stdout writeLine: OF_LOCALIZED(
					[OFStdOut writeString: @"\t"];
					[OFStdOut writeLine: OF_LOCALIZED(
					    @"list_extra_field",
					    @"Extra field: %[extra]",
					    @"extra",
					    entry.extraField.description)];
				}
			}

			if (entry.fileComment.length > 0) {
				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\t"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"list_comment",
				    @"Comment: %[comment]",
				    @"comment", entry.fileComment)];
			}
		}

		objc_autoreleasePoolPop(pool);
254
255
256
257
258
259
260
261

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
287
288
289
290
254
255
256
257
258
259
260

261
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
287
288
289
290







-
+









-
+










-
-
+
+







		if (!all && ![files containsObject: fileName])
			continue;

		[missing removeObject: fileName];

		outFileName = [app safeLocalPathForPath: fileName];
		if (outFileName == nil) {
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"refusing_to_extract_file",
			    @"Refusing to extract %[file]!",
			    @"file", fileName)];

			app->_exitStatus = 1;
			goto outer_loop_end;
		}

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"extracting_file",
			[OFStdOut writeString: OF_LOCALIZED(@"extracting_file",
			    @"Extracting %[file]...",
			    @"file", fileName)];

		if ([fileName hasSuffix: @"/"]) {
			[fileManager createDirectoryAtPath: outFileName
					     createParents: true];
			setPermissions(outFileName, entry);
			setModificationDate(outFileName, entry);

			if (app->_outputLevel >= 0) {
				[of_stdout writeString: @"\r"];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"\r"];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"extracting_file_done",
				    @"Extracting %[file]... done",
				    @"file", fileName)];
			}

			goto outer_loop_end;
		}
318
319
320
321
322
323
324
325
326


327
328
329
330
331
332
333
334
335
336
337
338
339


340
341
342
343
344
345
346
347
348
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
318
319
320
321
322
323
324


325
326
327
328
329
330
331
332
333
334
335
336
337


338
339
340
341
342
343
344
345
346
347
348
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







-
-
+
+











-
-
+
+











-
+













-
+










-
+












-
+

















-
+







			if (app->_outputLevel >= 0 && percent != newPercent) {
				OFString *percentString;

				percent = newPercent;
				percentString = [OFString stringWithFormat:
				    @"%3u", percent];

				[of_stdout writeString: @"\r"];
				[of_stdout writeString: OF_LOCALIZED(
				[OFStdOut writeString: @"\r"];
				[OFStdOut writeString: OF_LOCALIZED(
				    @"extracting_file_percent",
				    @"Extracting %[file]... %[percent]%",
				    @"file", fileName,
				    @"percent", percentString)];
			}
		}

		[output close];
		setModificationDate(outFileName, entry);

		if (app->_outputLevel >= 0) {
			[of_stdout writeString: @"\r"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\r"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"extracting_file_done",
			    @"Extracting %[file]... done",
			    @"file", fileName)];
		}

outer_loop_end:
		objc_autoreleasePoolPop(pool);
	}

	if (missing.count > 0) {
		for (OFString *file in missing)
			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"file_not_in_archive",
			    @"File %[file] is not in the archive!",
			    @"file", file)];

		app->_exitStatus = 1;
	}
}

- (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFStream *stream;

	if (files.count < 1) {
		[of_stderr writeLine: OF_LOCALIZED(@"print_no_file_specified",
		[OFStdErr writeLine: OF_LOCALIZED(@"print_no_file_specified",
		    @"Need one or more files to print!")];
		app->_exitStatus = 1;
		return;
	}

	for (OFString *path in files) {
		@try {
			stream = [_archive streamForReadingFile: path];
		} @catch (OFOpenItemFailedException *e) {
			if (e.errNo == ENOENT) {
				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"file_not_in_archive",
				    @"File %[file] is not in the archive!",
				    @"file", e.path)];
				app->_exitStatus = 1;
				continue;
			}

			@throw e;
		}

		while (!stream.atEndOfStream) {
			ssize_t length = [app copyBlockFromStream: stream
							 toStream: of_stdout
							 toStream: OFStdOut
							 fileName: path];

			if (length < 0) {
				app->_exitStatus = 1;
				return;
			}
		}

		[stream close];
	}
}

- (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFFileManager *fileManager = [OFFileManager defaultManager];

	if (files.count < 1) {
		[of_stderr writeLine: OF_LOCALIZED(@"add_no_file_specified",
		[OFStdErr writeLine: OF_LOCALIZED(@"add_no_file_specified",
		    @"Need one or more files to add!")];
		app->_exitStatus = 1;
		return;
	}

	for (OFString *localFileName in files) {
		void *pool = objc_autoreleasePoolPush();
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442







-
+








		if ([attributes.fileType isEqual: OFFileTypeDirectory]) {
			isDirectory = true;
			fileName = [fileName stringByAppendingString: @"/"];
		}

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"adding_file",
			[OFStdOut writeString: OF_LOCALIZED(@"adding_file",
			    @"Adding %[file]...",
			    @"file", fileName)];

		entry = [OFMutableZIPArchiveEntry entryWithFileName: fileName];

		size = (isDirectory ? 0 : attributes.fileSize);
		if (size > INT64_MAX)
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
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







-
-
+
+









-
-
+
+







				    percent != newPercent) {
					OFString *percentString;

					percent = newPercent;
					percentString = [OFString
					    stringWithFormat: @"%3u", percent];

					[of_stdout writeString: @"\r"];
					[of_stdout writeString: OF_LOCALIZED(
					[OFStdOut writeString: @"\r"];
					[OFStdOut writeString: OF_LOCALIZED(
					    @"adding_file_percent",
					    @"Adding %[file]... %[percent]%",
					    @"file", fileName,
					    @"percent", percentString)];
				}
			}
		}

		if (app->_outputLevel >= 0) {
			[of_stdout writeString: @"\r"];
			[of_stdout writeLine: OF_LOCALIZED(
			[OFStdOut writeString: @"\r"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"adding_file_done",
			    @"Adding %[file]... done",
			    @"file", fileName)];
		}

		[output close];

Modified utils/ofdns/OFDNS.m from [ca14e1ed43] to [bf91a28ab8].

31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45







-
+







@end

OF_APPLICATION_DELEGATE(OFDNS)

static void
help(OFStream *stream, bool full, int status)
{
	[of_stderr writeLine:
	[OFStdErr writeLine:
	    OF_LOCALIZED(@"usage",
	    @"Usage: %[prog] -[chst] domain1 [domain2 ...]",
	    @"prog", [OFApplication programName])];

	if (full) {
		[stream writeString: @"\n"];
		[stream writeLine: OF_LOCALIZED(@"full_usage",
63
64
65
66
67
68
69
70

71
72

73
74
75
76
77
78
79
63
64
65
66
67
68
69

70
71

72
73
74
75
76
77
78
79







-
+

-
+







  didPerformQuery: (OFDNSQuery *)query
	 response: (OFDNSResponse *)response
	exception: (id)exception
{
	_inFlight--;

	if (exception == nil)
		[of_stdout writeFormat: @"%@\n", response];
		[OFStdOut writeFormat: @"%@\n", response];
	else {
		[of_stderr writeLine: OF_LOCALIZED(
		[OFStdErr writeLine: OF_LOCALIZED(
		    @"failed_to_resolve",
		    @"Failed to resolve: %[exception]",
		    @"exception", exception)];
		_errors++;
	}

	if (_inFlight == 0)
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
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







-
+



-
+









-
+











-
+








-
+














-
+







	optionsParser = [OFOptionsParser parserWithOptions: options];
	while ((option = [optionsParser nextOption]) != '\0') {
		switch (option) {
		case 't':
			[recordTypes addObject: optionsParser.argument];
			break;
		case 'h':
			help(of_stdout, true, 0);
			help(OFStdOut, true, 0);
			break;
		case ':':
			if (optionsParser.lastLongOption != nil)
				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"long_option_required_argument",
				    @"%[prog]: Option --%[opt] requires an "
				    @"argument",
				    @"prog", [OFApplication programName],
				    @"opt", optionsParser.lastLongOption)];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%C",
				    optionsParser.lastOption];
				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"option_requires_argument",
				    @"%[prog]: Option -%[opt] requires an "
				    @"argument",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
			break;
		case '?':
			if (optionsParser.lastLongOption != nil)
				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"unknown_long_option",
				    @"%[prog]: Unknown option: --%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", optionsParser.lastLongOption)];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%C",
				    optionsParser.lastOption];
				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"Unknown_option",
				    @"%[prog]: Unknown option: -%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
			break;
		}
	}

	remainingArguments = optionsParser.remainingArguments;

	if (remainingArguments.count < 1)
		help(of_stderr, false, 1);
		help(OFStdErr, false, 1);

	resolver = [OFDNSResolver resolver];
	DNSClass = (DNSClassString != nil
	    ? OFDNSClassParseName(DNSClassString) : OFDNSClassIN);

	if (recordTypes.count == 0)
		[recordTypes addObject: @"ALL"];

Modified utils/ofhash/OFHash.m from [20916b6a0f] to [976db374f8].

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
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







-
+













-
+


-
+

-
+







@end

OF_APPLICATION_DELEGATE(OFHash)

static void
help(void)
{
	[of_stderr writeLine: OF_LOCALIZED(@"usage",
	[OFStdErr writeLine: OF_LOCALIZED(@"usage",
	    @"Usage: %[prog] [--md5|--ripemd160|--sha1|--sha224|--sha256|"
	    @"--sha384|--sha512] file1 [file2 ...]",
	    @"prog", [OFApplication programName])];

	[OFApplication terminateWithStatus: 1];
}

static void
printHash(OFString *algo, OFString *path, id <OFCryptographicHash> hash)
{
	const unsigned char *digest = hash.digest;
	size_t digestSize = hash.digestSize;

	[of_stdout writeFormat: @"%@ ", algo];
	[OFStdOut writeFormat: @"%@ ", algo];

	for (size_t i = 0; i < digestSize; i++)
		[of_stdout writeFormat: @"%02x", digest[i]];
		[OFStdOut writeFormat: @"%02x", digest[i]];

	[of_stdout writeFormat: @"  %@\n", path];
	[OFStdOut writeFormat: @"  %@\n", path];
}

@implementation OFHash
- (void)applicationDidFinishLaunching
{
	int exitStatus = 0;
	bool calculateMD5, calculateRIPEMD160, calculateSHA1, calculateSHA224;
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119







-
+







-
+







	[OFLocale addLanguageDirectory: @"PROGDIR:/share/ofhash/lang"];
#endif

	while ((option = [optionsParser nextOption]) != '\0') {
		switch (option) {
		case '?':
			if (optionsParser.lastLongOption != nil)
				[of_stderr writeLine:
				[OFStdErr writeLine:
				    OF_LOCALIZED(@"unknown_long_option",
				    @"%[prog]: Unknown option: --%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", optionsParser.lastLongOption)];
			else {
				OFString *optStr = [OFString stringWithFormat:
				    @"%c", optionsParser.lastOption];
				[of_stderr writeLine:
				[OFStdErr writeLine:
				    OF_LOCALIZED(@"unknown_option",
				    @"%[prog]: Unknown option: -%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187







-
+








-
+







		SHA512Hash = [OFSHA512Hash hashWithAllowsSwappableMemory: true];

	for (OFString *path in optionsParser.remainingArguments) {
		void *pool = objc_autoreleasePoolPush();
		OFStream *file;

		if ([path isEqual: @"-"])
			file = of_stdin;
			file = OFStdIn;
		else {
			@try {
				file = [OFFile fileWithPath: path mode: @"r"];
			} @catch (OFOpenItemFailedException *e) {
				OFString *error = [OFString
				    stringWithCString: strerror(e.errNo)
					     encoding: [OFLocale encoding]];

				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"failed_to_open_file",
				    @"Failed to open file %[file]: %[error]",
				    @"file", e.path,
				    @"error", error)];

				exitStatus = 1;
				goto outer_loop_end;
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218







-
+







				length = [file readIntoBuffer: buffer
						       length: 1024];
			} @catch (OFReadFailedException *e) {
				OFString *error = [OFString
				    stringWithCString: strerror(e.errNo)
					     encoding: [OFLocale encoding]];

				[of_stderr writeLine: OF_LOCALIZED(
				[OFStdErr writeLine: OF_LOCALIZED(
				    @"failed_to_read_file",
				    @"Failed to read %[file]: %[error]",
				    @"file", path,
				    @"error", error)];

				exitStatus = 1;
				goto outer_loop_end;

Modified utils/ofhttp/OFHTTP.m from [b78631e300] to [fa0717c415].

79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93







-
+







@end

OF_APPLICATION_DELEGATE(OFHTTP)

static void
help(OFStream *stream, bool full, int status)
{
	[of_stderr writeLine:
	[OFStdErr writeLine:
	    OF_LOCALIZED(@"usage",
	    @"Usage: %[prog] -[cehHmoOPqv] url1 [url2 ...]",
	    @"prog", [OFApplication programName])];

	if (full) {
		[stream writeString: @"\n"];
		[stream writeLine: OF_LOCALIZED(@"full_usage",
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295







-
+







#ifdef OF_HAVE_PLUGINS
+ (void)initialize
{
	if (self != [OFHTTP class])
		return;

	/* Opportunistically try loading ObjOpenSSL and ignore any errors. */
	OFDlopen(@LIB_PREFIX @"objopenssl" @LIB_SUFFIX, OF_RTLD_LAZY);
	OFDlOpen(@LIB_PREFIX @"objopenssl" @LIB_SUFFIX, OF_RTLD_LAZY);
}
#endif

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

314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328







-
+








- (void)addHeader: (OFString *)header
{
	size_t pos = [header rangeOfString: @":"].location;
	OFString *name, *value;

	if (pos == OFNotFound) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_input_header",
		[OFStdErr writeLine: OF_LOCALIZED(@"invalid_input_header",
		    @"%[prog]: Headers must to be in format name:value!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	name = [header substringToIndex: pos]
	    .stringByDeletingEnclosingWhitespaces;
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351







-
+







{
	OFString *contentLength = nil;

	[_body release];
	_body = nil;

	if ([path isEqual: @"-"])
		_body = [of_stdin copy];
		_body = [OFStdIn copy];
	else {
		_body = [[OFFile alloc] initWithPath: path mode: @"r"];

		@try {
			unsigned long long fileSize =
			    [[OFFileManager defaultManager]
			    attributesOfItemAtPath: path].fileSize;
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382







-
+







	void *pool = objc_autoreleasePoolPush();

	method = method.uppercaseString;

	@try {
		_method = OFHTTPRequestMethodParseName(method);
	} @catch (OFInvalidArgumentException *e) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_input_method",
		[OFStdErr writeLine: OF_LOCALIZED(@"invalid_input_method",
		    @"%[prog]: Invalid request method %[method]!",
		    @"prog", [OFApplication programName],
		    @"method", method)];
		[OFApplication terminateWithStatus: 1];
	}

	objc_autoreleasePoolPop(pool);
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414







-
+








		if (port > UINT16_MAX)
			@throw [OFOutOfRangeException exception];

		[OFTCPSocket setSOCKS5Host: host];
		[OFTCPSocket setSOCKS5Port: (uint16_t)port];
	} @catch (OFInvalidFormatException *e) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_input_proxy",
		[OFStdErr writeLine: OF_LOCALIZED(@"invalid_input_proxy",
		    @"%[prog]: Proxy must to be in format host:port!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}
}

- (void)applicationDidFinishLaunching
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
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







-
+












-
+









-
+










-
+









-
+








-
+







	optionsParser = [OFOptionsParser parserWithOptions: options];
	while ((option = [optionsParser nextOption]) != '\0') {
		switch (option) {
		case 'b':
			[self setBody: optionsParser.argument];
			break;
		case 'h':
			help(of_stdout, true, 0);
			help(OFStdOut, true, 0);
			break;
		case 'H':
			[self addHeader: optionsParser.argument];
			break;
		case 'm':
			[self setMethod: optionsParser.argument];
			break;
		case 'P':
			[self setProxy: optionsParser.argument];
			break;
		case ':':
			if (optionsParser.lastLongOption != nil)
				[of_stderr writeLine:
				[OFStdErr writeLine:
				    OF_LOCALIZED(@"long_argument_missing",
				    @"%[prog]: Argument for option --%[opt] "
				    @"missing"
				    @"prog", [OFApplication programName],
				    @"opt", optionsParser.lastLongOption)];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%c",
				    optionsParser.lastOption];
				[of_stderr writeLine:
				[OFStdErr writeLine:
				    OF_LOCALIZED(@"argument_missing",
				    @"%[prog]: Argument for option -%[opt] "
				    @"missing",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
			break;
		case '=':
			[of_stderr writeLine:
			[OFStdErr writeLine:
			    OF_LOCALIZED(@"option_takes_no_argument",
			    @"%[prog]: Option --%[opt] takes no argument",
			    @"prog", [OFApplication programName],
			    @"opt", optionsParser.lastLongOption)];

			[OFApplication terminateWithStatus: 1];
			break;
		case '?':
			if (optionsParser.lastLongOption != nil)
				[of_stderr writeLine:
				[OFStdErr writeLine:
				    OF_LOCALIZED(@"unknown_long_option",
				    @"%[prog]: Unknown option: --%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", optionsParser.lastLongOption)];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%c",
				    optionsParser.lastOption];
				[of_stderr writeLine:
				[OFStdErr writeLine:
				    OF_LOCALIZED(@"unknown_option",
				    @"%[prog]: Unknown option: -%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
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
572
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
572







-
+


-
+







-
+








-
+







	[OFApplication of_activateSandbox: sandbox];
#endif

	_outputPath = [outputPath copy];
	_URLs = [optionsParser.remainingArguments copy];

	if (_URLs.count < 1)
		help(of_stderr, false, 1);
		help(OFStdErr, false, 1);

	if (_quiet && _verbose) {
		[of_stderr writeLine: OF_LOCALIZED(@"quiet_xor_verbose",
		[OFStdErr writeLine: OF_LOCALIZED(@"quiet_xor_verbose",
		    @"%[prog]: -q / --quiet and -v / --verbose are mutually "
		    @"exclusive!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	if (_outputPath != nil && _detectFileName) {
		[of_stderr writeLine: OF_LOCALIZED(
		[OFStdErr writeLine: OF_LOCALIZED(
		    @"output_xor_detect_filename",
		    @"%[prog]: -o / --output and -O / --detect-filename are "
		    @"mutually exclusive!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	if (_outputPath != nil && _URLs.count > 1) {
		[of_stderr writeLine:
		[OFStdErr writeLine:
		    OF_LOCALIZED(@"output_only_with_one_url",
		    @"%[prog]: Cannot use -o / --output when more than one URL "
		    @"has been specified!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

611
612
613
614
615
616
617
618

619
620
621
622
623
624
625

626
627

628
629
630
631
632
633
634
611
612
613
614
615
616
617

618
619
620
621
622
623
624

625
626

627
628
629
630
631
632
633
634







-
+






-
+

-
+







		    response.headers;
		OFEnumerator *keyEnumerator = [headers keyEnumerator];
		OFEnumerator *objectEnumerator = [headers objectEnumerator];
		OFString *key, *object;

		while ((key = [keyEnumerator nextObject]) != nil &&
		    (object = [objectEnumerator nextObject]) != nil)
			[of_stdout writeFormat: @"  %@: %@\n", key, object];
			[OFStdOut writeFormat: @"  %@: %@\n", key, object];

		objc_autoreleasePoolPop(pool);
	}

	if (!_quiet) {
		if (_useUnicode)
			[of_stdout writeFormat: @"☇ %@", URL.string];
			[OFStdOut writeFormat: @"☇ %@", URL.string];
		else
			[of_stdout writeFormat: @"< %@", URL.string];
			[OFStdOut writeFormat: @"< %@", URL.string];
	}

	_length = 0;

	return true;
}

642
643
644
645
646
647
648
649
650


651
652
653
654
655

656
657
658
659
660
661
662
642
643
644
645
646
647
648


649
650
651
652
653
654

655
656
657
658
659
660
661
662







-
-
+
+




-
+








		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet) {
			[of_stdout writeString: @"\n  "];
			[of_stdout writeLine: OF_LOCALIZED(@"download_error",
			[OFStdOut writeString: @"\n  "];
			[OFStdOut writeLine: OF_LOCALIZED(@"download_error",
			    @"Error!")];
		}

		URL = [_URLs objectAtIndex: _URLIndex - 1];
		[of_stderr writeLine: OF_LOCALIZED(
		[OFStdErr writeLine: OF_LOCALIZED(
		    @"download_failed_exception",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", URL,
		    @"exception", exception)];

674
675
676
677
678
679
680
681
682


683
684
685
686
687
688
689
674
675
676
677
678
679
680


681
682
683
684
685
686
687
688
689







-
-
+
+







	if (response.atEndOfStream) {
		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet) {
			[of_stdout writeString: @"\n  "];
			[of_stdout writeLine:
			[OFStdOut writeString: @"\n  "];
			[OFStdOut writeLine:
			    OF_LOCALIZED(@"download_done", @"Done!")];
		}

		[self performSelector: @selector(downloadNextURL)
			   afterDelay: 0];
		return false;
	}
701
702
703
704
705
706
707
708

709
710

711
712
713
714
715
716
717
701
702
703
704
705
706
707

708
709

710
711
712
713
714
715
716
717







-
+

-
+








	if (!_quiet) {
		OFString *lengthString =
		    [headers objectForKey: @"Content-Length"];
		OFString *type = [headers objectForKey: @"Content-Type"];

		if (_useUnicode)
			[of_stdout writeFormat: @" ➜ %hd\n", statusCode];
			[OFStdOut writeFormat: @" ➜ %hd\n", statusCode];
		else
			[of_stdout writeFormat: @" -> %hd\n", statusCode];
			[OFStdOut writeFormat: @" -> %hd\n", statusCode];

		if (type == nil)
			type = OF_LOCALIZED(@"type_unknown", @"unknown");

		if (lengthString != nil) {
			_length = lengthString.unsignedLongLongValue;

757
758
759
760
761
762
763
764
765


766
767
768
769
770
771
772
773
774


775
776
777
778

779
780
781

782
783
784
785
786


787
788
789
790


791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806

807
808

809
810
811
812
813
814
815
816
817
818

819
820

821
822
823
824
825
826
827
828
829
830

831
832

833
834
835
836
837
838
839
840
841

842
843

844
845
846
847
848
849
850
851
852
853
854
855
856

857
858
859
860
861
862
863
864
865
866
867
868
869
870
871

872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892

893
894
895
896
897
898
899
757
758
759
760
761
762
763


764
765
766
767
768
769
770
771
772


773
774
775
776
777

778
779
780

781
782
783
784


785
786
787
788


789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805

806
807

808
809
810
811
812
813
814
815
816
817

818
819

820
821
822
823
824
825
826
827
828
829

830
831

832
833
834
835
836
837
838
839
840

841
842

843
844
845
846
847
848
849
850
851
852
853
854
855

856
857
858
859
860
861
862
863
864
865
866
867
868
869
870

871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891

892
893
894
895
896
897
898
899







-
-
+
+







-
-
+
+



-
+


-
+



-
-
+
+


-
-
+
+















-
+

-
+









-
+

-
+









-
+

-
+








-
+

-
+












-
+














-
+




















-
+







			OFEnumerator OF_GENERIC(OFString *) *keyEnumerator =
			    [headers keyEnumerator];
			OFEnumerator OF_GENERIC(OFString *) *objectEnumerator =
			    [headers objectEnumerator];
			OFString *key, *object;

			if (statusCode / 100 == 2 && _currentFileName != nil) {
				[of_stdout writeString: @"  "];
				[of_stdout writeLine: OF_LOCALIZED(
				[OFStdOut writeString: @"  "];
				[OFStdOut writeLine: OF_LOCALIZED(
				    @"info_name_unaligned",
				    @"Name: %[name]",
				    @"name", _currentFileName)];
			}

			while ((key = [keyEnumerator nextObject]) != nil &&
			    (object = [objectEnumerator nextObject]) != nil)
				[of_stdout writeFormat: @"  %@: %@\n",
							key, object];
				[OFStdOut writeFormat: @"  %@: %@\n",
						       key, object];

			objc_autoreleasePoolPop(pool);
		} else if (statusCode / 100 == 2 && !_detectFileNameRequest) {
			[of_stdout writeString: @"  "];
			[OFStdOut writeString: @"  "];

			if (_currentFileName != nil)
				[of_stdout writeLine: OF_LOCALIZED(@"info_name",
				[OFStdOut writeLine: OF_LOCALIZED(@"info_name",
				    @"Name: %[name]",
				    @"name", _currentFileName)];

			[of_stdout writeString: @"  "];
			[of_stdout writeLine: OF_LOCALIZED(@"info_type",
			[OFStdOut writeString: @"  "];
			[OFStdOut writeLine: OF_LOCALIZED(@"info_type",
			    @"Type: %[type]",
			    @"type", type)];
			[of_stdout writeString: @"  "];
			[of_stdout writeLine: OF_LOCALIZED(@"info_size",
			[OFStdOut writeString: @"  "];
			[OFStdOut writeLine: OF_LOCALIZED(@"info_size",
			    @"Size: %[size]",
			    @"size", lengthString)];
		}
	}
}

-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response
	  exception: (id)exception
{
	if (exception != nil) {
		if ([exception isKindOfClass:
		    [OFResolveHostFailedException class]]) {
			if (!_quiet)
				[of_stdout writeString: @"\n"];
				[OFStdOut writeString: @"\n"];

			[of_stderr writeLine:
			[OFStdErr writeLine:
			    OF_LOCALIZED(@"download_resolve_host_failed",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  Failed to resolve host: %[exception]",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string,
			    @"exception", exception)];
		} else if ([exception isKindOfClass:
		    [OFConnectionFailedException class]]) {
			if (!_quiet)
				[of_stdout writeString: @"\n"];
				[OFStdOut writeString: @"\n"];

			[of_stderr writeLine:
			[OFStdErr writeLine:
			    OF_LOCALIZED(@"download_failed_connection_failed",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  Connection failed: %[exception]",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string,
			    @"exception", exception)];
		} else if ([exception isKindOfClass:
		    [OFInvalidServerReplyException class]]) {
			if (!_quiet)
				[of_stdout writeString: @"\n"];
				[OFStdOut writeString: @"\n"];

			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"download_failed_invalid_server_reply",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  Invalid server reply!",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string)];
		} else if ([exception isKindOfClass:
		    [OFUnsupportedProtocolException class]]) {
			if (!_quiet)
				[of_stdout writeString: @"\n"];
				[OFStdOut writeString: @"\n"];

			[of_stderr writeLine: OF_LOCALIZED(@"no_ssl_library",
			[OFStdErr writeLine: OF_LOCALIZED(@"no_ssl_library",
			    @"%[prog]: No TLS library loaded!\n"
			    @"  In order to download via https, you need to "
			    @"preload an TLS library for ObjFW\n"
			    @"  such as ObjOpenSSL!",
			    @"prog", [OFApplication programName])];
		} else if ([exception isKindOfClass:
		    [OFReadOrWriteFailedException class]]) {
			OFString *error = OF_LOCALIZED(
			    @"download_failed_read_or_write_failed_any",
			    @"Read or write failed");

			if (!_quiet)
				[of_stdout writeString: @"\n"];
				[OFStdOut writeString: @"\n"];

			if ([exception isKindOfClass:
			    [OFReadFailedException class]])
				error = OF_LOCALIZED(
				    @"download_failed_read_or_write_failed_"
				    @"read",
				    @"Read failed");
			else if ([exception isKindOfClass:
			    [OFWriteFailedException class]])
				error = OF_LOCALIZED(
				    @"download_failed_read_or_write_failed_"
				    @"write",
				    @"Write failed");

			[of_stderr writeLine: OF_LOCALIZED(
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"download_failed_read_or_write_failed",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  %[error]: %[exception]",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string,
			    @"error", error,
			    @"exception", exception)];
		} else if ([exception isKindOfClass:
		    [OFHTTPRequestFailedException class]]) {
			short statusCode;
			OFString *codeString;

			if (_ignoreStatus) {
				exception = nil;
				goto after_exception_handling;
			}

			statusCode = response.statusCode;
			codeString = [OFString stringWithFormat: @"%hd %@",
			    statusCode, OFHTTPStatusCodeString(statusCode)];
			[of_stderr writeLine: OF_LOCALIZED(@"download_failed",
			[OFStdErr writeLine: OF_LOCALIZED(@"download_failed",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  HTTP status code: %[code]",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string,
			    @"code", codeString)];
		} else
			@throw exception;
919
920
921
922
923
924
925
926

927
928
929
930

931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946

947
948
949
950
951
952
953
919
920
921
922
923
924
925

926
927
928
929

930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945

946
947
948
949
950
951
952
953







-
+



-
+















-
+








		[self performSelector: @selector(downloadNextURL)
			   afterDelay: 0];
		return;
	}

	if ([_outputPath isEqual: @"-"])
		_output = of_stdout;
		_output = [OFStdOut copy];
	else {
		if (!_continue && !_force && [[OFFileManager defaultManager]
		    fileExistsAtPath: _currentFileName]) {
			[of_stderr writeLine:
			[OFStdErr writeLine:
			    OF_LOCALIZED(@"output_already_exists",
			    @"%[prog]: File %[filename] already exists!",
			    @"prog", [OFApplication programName],
			    @"filename", _currentFileName)];

			_errorCode = 1;
			goto next;
		}

		@try {
			OFString *mode =
			    (response.statusCode == 206 ? @"a" : @"w");
			_output = [[OFFile alloc] initWithPath: _currentFileName
							  mode: mode];
		} @catch (OFOpenItemFailedException *e) {
			[of_stderr writeLine:
			[OFStdErr writeLine:
			    OF_LOCALIZED(@"failed_to_open_output",
			    @"%[prog]: Failed to open file %[filename]: "
			    @"%[exception]",
			    @"prog", [OFApplication programName],
			    @"filename", _currentFileName,
			    @"exception", e)];

984
985
986
987
988
989
990
991

992
993
994
995
996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026

1027
1028

1029
1030
1031
1032
1033
1034
1035
984
985
986
987
988
989
990

991
992
993
994
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025

1026
1027

1028
1029
1030
1031
1032
1033
1034
1035







-
+










-
+









-
+













-
+

-
+







	OFString *URLString = nil;
	OFURL *URL;
	OFMutableDictionary *clientHeaders;
	OFHTTPRequest *request;

	_received = _length = _resumedFrom = 0;

	if (_output != of_stdout)
	if (_output != OFStdOut)
		[_output release];
	_output = nil;

	if (_URLIndex >= _URLs.count)
		[OFApplication terminateWithStatus: _errorCode];

	@try {
		URLString = [_URLs objectAtIndex: _URLIndex++];
		URL = [OFURL URLWithString: URLString];
	} @catch (OFInvalidFormatException *e) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_url",
		[OFStdErr writeLine: OF_LOCALIZED(@"invalid_url",
		    @"%[prog]: Invalid URL: <%[url]>!",
		    @"prog", [OFApplication programName],
		    @"url", URLString)];

		_errorCode = 1;
		goto next;
	}

	if (![URL.scheme isEqual: @"http"] && ![URL.scheme isEqual: @"https"]) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_scheme",
		[OFStdErr writeLine: OF_LOCALIZED(@"invalid_scheme",
		    @"%[prog]: Invalid scheme: <%[url]>!",
		    @"prog", [OFApplication programName],
		    @"url", URLString)];

		_errorCode = 1;
		goto next;
	}

	clientHeaders = [[_clientHeaders mutableCopy] autorelease];

	if (_detectFileName && !_detectedFileName) {
		if (!_quiet) {
			if (_useUnicode)
				[of_stdout writeFormat: @"⠒ %@", URL.string];
				[OFStdOut writeFormat: @"⠒ %@", URL.string];
			else
				[of_stdout writeFormat: @"? %@", URL.string];
				[OFStdOut writeFormat: @"? %@", URL.string];
		}

		request = [OFHTTPRequest requestWithURL: URL];
		request.headers = clientHeaders;
		request.method = OFHTTPRequestMethodHead;

		_detectFileNameRequest = true;
1074
1075
1076
1077
1078
1079
1080
1081

1082
1083

1084
1085
1086
1087
1088
1089
1090
1074
1075
1076
1077
1078
1079
1080

1081
1082

1083
1084
1085
1086
1087
1088
1089
1090







-
+

-
+







			[clientHeaders setObject: range forKey: @"Range"];
		} @catch (OFRetrieveItemAttributesFailedException *e) {
		}
	}

	if (!_quiet) {
		if (_useUnicode)
			[of_stdout writeFormat: @"⇣ %@", URL.string];
			[OFStdOut writeFormat: @"⇣ %@", URL.string];
		else
			[of_stdout writeFormat: @"< %@", URL.string];
			[OFStdOut writeFormat: @"< %@", URL.string];
	}

	request = [OFHTTPRequest requestWithURL: URL];
	request.headers = clientHeaders;
	request.method = _method;

	_detectFileNameRequest = false;

Modified utils/ofhttp/ProgressBar.m from [3a96d93eb6] to [df2864a1e1].

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
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
252
253

254
255
256
257
258
259

260
261
262
263
264
265

266
267
268
269
270
271

272
273
274
275
276
277
278
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

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
252

253
254
255
256
257
258

259
260
261
262
263
264

265
266
267
268
269
270

271
272
273
274
275
276
277
278







-
+













-
+


-
+




-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+


-
+


-
+

-
+


-
+




-
+

-
+

-
+

-
+


-
+


-
+










-
+



-
+



-
+






-
+





-
+





-
+





-
+







-
+




-
+





-
+





-
+





-
+









-
+








-
+





-
+





-
+





-
+







}

- (void)_drawProgress
{
	float bars, percent;
	int columns, barWidth;

	if ((columns = of_stdout.columns) >= 0) {
	if ((columns = OFStdOut.columns) >= 0) {
		if (columns > 37)
			barWidth = columns - 37;
		else
			barWidth = 0;
	} else
		barWidth = 43;

	bars = (float)(_resumedFrom + _received) /
	    (float)(_resumedFrom + _length) * barWidth;
	percent = (float)(_resumedFrom + _received) /
	    (float)(_resumedFrom + _length) * 100;

	if (_useUnicode) {
		[of_stdout writeString: @"\r  ▕"];
		[OFStdOut writeString: @"\r  ▕"];

		for (size_t i = 0; i < (size_t)bars; i++)
			[of_stdout writeString: @"█"];
			[OFStdOut writeString: @"█"];
		if (bars < barWidth) {
			float rem = bars - truncf(bars);

			if (rem >= 0.875)
				[of_stdout writeString: @"▉"];
				[OFStdOut writeString: @"▉"];
			else if (rem >= 0.75)
				[of_stdout writeString: @"▊"];
				[OFStdOut writeString: @"▊"];
			else if (rem >= 0.625)
				[of_stdout writeString: @"▋"];
				[OFStdOut writeString: @"▋"];
			else if (rem >= 0.5)
				[of_stdout writeString: @"▌"];
				[OFStdOut writeString: @"▌"];
			else if (rem >= 0.375)
				[of_stdout writeString: @"▍"];
				[OFStdOut writeString: @"▍"];
			else if (rem >= 0.25)
				[of_stdout writeString: @"▎"];
				[OFStdOut writeString: @"▎"];
			else if (rem >= 0.125)
				[of_stdout writeString: @"▏"];
				[OFStdOut writeString: @"▏"];
			else
				[of_stdout writeString: @" "];
				[OFStdOut writeString: @" "];

			for (size_t i = 0; i < barWidth - (size_t)bars - 1; i++)
				[of_stdout writeString: @" "];
				[OFStdOut writeString: @" "];
		}

		[of_stdout writeFormat: @"▏ %,6.2f%% ", percent];
		[OFStdOut writeFormat: @"▏ %,6.2f%% ", percent];
	} else {
		[of_stdout writeString: @"\r  ["];
		[OFStdOut writeString: @"\r  ["];

		for (size_t i = 0; i < (size_t)bars; i++)
			[of_stdout writeString: @"#"];
			[OFStdOut writeString: @"#"];
		if (bars < barWidth) {
			float rem = bars - truncf(bars);

			if (rem >= 0.75)
				[of_stdout writeString: @"O"];
				[OFStdOut writeString: @"O"];
			else if (rem >= 0.5)
				[of_stdout writeString: @"o"];
				[OFStdOut writeString: @"o"];
			else if (rem >= 0.25)
				[of_stdout writeString: @"."];
				[OFStdOut writeString: @"."];
			else
				[of_stdout writeString: @" "];
				[OFStdOut writeString: @" "];

			for (size_t i = 0; i < barWidth - (size_t)bars - 1; i++)
				[of_stdout writeString: @" "];
				[OFStdOut writeString: @" "];
		}

		[of_stdout writeFormat: @"] %,6.2f%% ", percent];
		[OFStdOut writeFormat: @"] %,6.2f%% ", percent];
	}

	if (percent == 100) {
		double timeInterval = -_startDate.timeIntervalSinceNow;

		_BPS = (float)_received / (float)timeInterval;
		_ETA = timeInterval;
	}

	if (isinf(_ETA))
		[of_stdout writeString: @"--:--:-- "];
		[OFStdOut writeString: @"--:--:-- "];
	else if (_ETA >= 99 * 3600) {
		OFString *num = [OFString stringWithFormat:
		    @"%,4.2f", _ETA / (24 * 3600)];
		[of_stdout writeString: OF_LOCALIZED(@"eta_days",
		[OFStdOut writeString: OF_LOCALIZED(@"eta_days",
		    @"%[num] d ",
		    @"num", num)];
	} else
		[of_stdout writeFormat: @"%2u:%02u:%02u ",
		[OFStdOut writeFormat: @"%2u:%02u:%02u ",
		    (uint8_t)(_ETA / 3600), (uint8_t)(_ETA / 60) % 60,
		    (uint8_t)_ETA % 60];

	if (_BPS >= GIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", _BPS / GIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_gibs",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_gibs",
		    @"%[num] GiB/s",
		    @"num", num)];
	} else if (_BPS >= MEBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", _BPS / MEBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_mibs",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_mibs",
		    @"%[num] MiB/s",
		    @"num", num)];
	} else if (_BPS >= KIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", _BPS / KIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_kibs",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_kibs",
		    @"%[num] KiB/s",
		    @"num", num)];
	} else {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", _BPS];
		[of_stdout writeString: OF_LOCALIZED(@"progress_bps",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_bps",
		    @"%[num] B/s  ",
		    @"num", num)];
	}
}

- (void)_drawReceived
{
	[of_stdout writeString: @"\r  "];
	[OFStdOut writeString: @"\r  "];

	if (_resumedFrom + _received >= GIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", (float)(_resumedFrom + _received) / GIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_gib",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_gib",
		    @"%[num] GiB",
		    @"num", num)];
	} else if (_resumedFrom + _received >= MEBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", (float)(_resumedFrom + _received) / MEBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_mib",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_mib",
		    @"%[num] MiB",
		    @"num", num)];
	} else if (_resumedFrom + _received >= KIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", (float)(_resumedFrom + _received) / KIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_kib",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_kib",
		    @"%[num] KiB",
		    @"num", num)];
	} else {
		OFString *num = [OFString stringWithFormat:
		    @"%jd", _resumedFrom + _received];
		[of_stdout writeString: OF_LOCALIZED(@"progress_bytes",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_bytes",
		    @"["
		    @"    ["
		    @"        {'num == 1': '1 byte '},"
		    @"        {'': '%[num] bytes'}"
		    @"    ]"
		    @"]".objectByParsingJSON,
		    @"num", num)];
	}

	[of_stdout writeString: @" "];
	[OFStdOut writeString: @" "];

	if (_stopped)
		_BPS = (float)_received /
		    -(float)_startDate.timeIntervalSinceNow;

	if (_BPS >= GIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", _BPS / GIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_gibs",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_gibs",
		    @"%[num] GiB/s",
		    @"num", num)];
	} else if (_BPS >= MEBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", _BPS / MEBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_mibs",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_mibs",
		    @"%[num] MiB/s",
		    @"num", num)];
	} else if (_BPS >= KIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", _BPS / KIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_kibs",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_kibs",
		    @"%[num] KiB/s",
		    @"num", num)];
	} else {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", _BPS];
		[of_stdout writeString: OF_LOCALIZED(@"progress_bps",
		[OFStdOut writeString: OF_LOCALIZED(@"progress_bps",
		    @"%[num] B/s  ",
		    @"num", num)];
	}
}

- (void)draw
{