ObjFW  Check-in [62edb405b9]

Overview
Comment:Merge trunk into 1.0 branch
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | 1.0
Files: files | file ages | folders
SHA3-256: 62edb405b99d1ba07ce40943f62985b715f35f00f6ada9891d77c977fcff9d13
User & Date: js on 2020-12-22 20:19:50
Other Links: branch diff | manifest | tags
Context
2021-03-08
00:07
src/Makefile: Indentation fix check-in: b87baa7fd6 user: js tags: 1.0
2020-12-22
20:19
Merge trunk into 1.0 branch check-in: 62edb405b9 user: js tags: 1.0
20:15
Fix files accidentally being executable check-in: 55fdd76bb7 user: js tags: trunk
13:16
Make OFSandbox private check-in: 510628432f user: js tags: 1.0
Changes

Modified build-aux/config.guess from [3b75d9d5f8] to [a7bb5831a2].

1
2
3

4
5

6
7
8
9
10
11
12
1
2

3
4

5
6
7
8
9
10
11
12


-
+

-
+







#! /bin/sh
# Attempt to guess a canonical system name.
#   Copyright 1992-2018 Free Software Foundation, Inc.
#   Copyright 1992-2019 Free Software Foundation, Inc.

timestamp='2018-03-08'
timestamp='2019-01-03'

# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
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







-
+








Report bugs and patches to <config-patches@gnu.org>."

version="\
GNU config.guess ($timestamp)

Originally written by Per Bothner.
Copyright 1992-2018 Free Software Foundation, Inc.
Copyright 1992-2019 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."

help="
Try \`$me --help' for more information."

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98




99

100
101
102
103
104
105
106
107







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

















124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
80
81
82
83
84
85
86


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

101








102
103
104
105
106
107
108
















109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150







-
-










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


-
+














-
+







done

if test $# != 0; then
  echo "$me: too many arguments$help" >&2
  exit 1
fi

trap 'exit 1' 1 2 15

# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.

# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.

# Portable tmp directory creation inspired by the Autoconf team.

tmp=
# shellcheck disable=SC2172
trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15

set_cc_for_build='
set_cc_for_build() {
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
 { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
 { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
 { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
    : "${TMPDIR=/tmp}"
    # shellcheck disable=SC2039
    { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
    dummy=$tmp/dummy
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
 ,,)    echo "int x;" > "$dummy.c" ;
	for c in cc gcc c89 c99 ; do
	  if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
	     CC_FOR_BUILD="$c"; break ;
	  fi ;
	done ;
	if test x"$CC_FOR_BUILD" = x ; then
	  CC_FOR_BUILD=no_compiler_found ;
	fi
	;;
 ,,*)   CC_FOR_BUILD=$CC ;;
 ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
esac ; set_cc_for_build= ;'

    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
	,,)    echo "int x;" > "$dummy.c"
	       for driver in cc gcc c89 c99 ; do
		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
		       CC_FOR_BUILD="$driver"
		       break
		   fi
	       done
	       if test x"$CC_FOR_BUILD" = x ; then
		   CC_FOR_BUILD=no_compiler_found
	       fi
	       ;;
	,,*)   CC_FOR_BUILD=$CC ;;
	,*,*)  CC_FOR_BUILD=$HOST_CC ;;
    esac
}

# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
if test -f /.attbin/uname ; then
	PATH=$PATH:/.attbin ; export PATH
fi

UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown

case "$UNAME_SYSTEM" in
Linux|GNU|GNU/*)
	# If the system lacks a compiler, then just pick glibc.
	# We could probably try harder.
	LIBC=gnu

	eval "$set_cc_for_build"
	set_cc_for_build
	cat <<-EOF > "$dummy.c"
	#include <features.h>
	#if defined(__UCLIBC__)
	LIBC=uclibc
	#elif defined(__dietlibc__)
	LIBC=dietlibc
	#else
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
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







+





-
-
+
+
+
+












-
+

















-
+



















-
+







	# portion of the name.  We always set it to "unknown".
	sysctl="sysctl -n hw.machine_arch"
	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
	    "/sbin/$sysctl" 2>/dev/null || \
	    "/usr/sbin/$sysctl" 2>/dev/null || \
	    echo unknown)`
	case "$UNAME_MACHINE_ARCH" in
	    aarch64eb) machine=aarch64_be-unknown ;;
	    armeb) machine=armeb-unknown ;;
	    arm*) machine=arm-unknown ;;
	    sh3el) machine=shl-unknown ;;
	    sh3eb) machine=sh-unknown ;;
	    sh5el) machine=sh5le-unknown ;;
	    earmv*)
		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
	    earm*)
		arch="${UNAME_MACHINE_ARCH#e}"
		arch="${arch%eb}"
		arch="${arch%hf}"
		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
		machine="${arch}${endian}"-unknown
		;;
	    *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
	esac
	# The Operating System including object format, if it has switched
	# to ELF recently (or will in the future) and ABI.
	case "$UNAME_MACHINE_ARCH" in
	    earm*)
		os=netbsdelf
		;;
	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
		eval "$set_cc_for_build"
		set_cc_for_build
		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
			| grep -q __ELF__
		then
		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
		    # Return netbsd for either.  FIX?
		    os=netbsd
		else
		    os=netbsdelf
		fi
		;;
	    *)
		os=netbsd
		;;
	esac
	# Determine ABI tags.
	case "$UNAME_MACHINE_ARCH" in
	    earm*)
		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
		expr='s/v[0-9]//;s/earm/-eabi/;s/eb$//'
		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
		;;
	esac
	# The OS release
	# Debian GNU/NetBSD machines have a different userland, and
	# thus, need a distinct triplet. However, they do not need
	# kernel version information, so it can be replaced with a
	# suitable tag, in the style of linux-gnu.
	case "$UNAME_VERSION" in
	    Debian*)
		release='-gnu'
		;;
	    *)
		release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
		;;
	esac
	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
	# contains redundant information, the shorter form:
	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
	echo "$machine-${os}${release}${abi}"
	echo "$machine-${os}${release}${abi-}"
	exit ;;
    *:Bitrig:*:*)
	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
	echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
	exit ;;
    *:OpenBSD:*:*)
	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
379
380
381
382
383
384
385













386

387
388
389
390
391
392

393
394
395
396
397
398
399
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







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





-
+







    s390x:SunOS:*:*)
	echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
	exit ;;
    sun4H:SunOS:5.*:*)
	echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
	exit ;;
    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
	set_cc_for_build
	SUN_ARCH=sparc
	# If there is a compiler, see if it is configured for 64-bit objects.
	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
	# This test works for both compilers.
	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
	    if (echo '#ifdef __sparcv9'; echo IS_64BIT_ARCH; echo '#endif') | \
		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
		grep IS_64BIT_ARCH >/dev/null
	    then
		SUN_ARCH=sparcv9
	    fi
	fi
	echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
	echo "$SUN_ARCH"-sun-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
	exit ;;
    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
	echo i386-pc-auroraux"$UNAME_RELEASE"
	exit ;;
    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
	eval "$set_cc_for_build"
	set_cc_for_build
	SUN_ARCH=i386
	# If there is a compiler, see if it is configured for 64-bit objects.
	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
	# This test works for both compilers.
	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
478
479
480
481
482
483
484
485

486
487
488
489
490
491
492
496
497
498
499
500
501
502

503
504
505
506
507
508
509
510







-
+







    VAX*:ULTRIX*:*:*)
	echo vax-dec-ultrix"$UNAME_RELEASE"
	exit ;;
    2020:CLIX:*:* | 2430:CLIX:*:*)
	echo clipper-intergraph-clix"$UNAME_RELEASE"
	exit ;;
    mips:*:*:UMIPS | mips:*:*:RISCos)
	eval "$set_cc_for_build"
	set_cc_for_build
	sed 's/^	//' << EOF > "$dummy.c"
#ifdef __cplusplus
#include <stdio.h>  /* for printf() prototype */
	int main (int argc, char *argv[]) {
#else
	int main (argc, argv) int argc; char *argv[]; {
#endif
575
576
577
578
579
580
581
582

583
584
585
586
587
588
589
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607







-
+







	else
		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
	fi
	echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
	exit ;;
    *:AIX:2:3)
	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
		eval "$set_cc_for_build"
		set_cc_for_build
		sed 's/^		//' << EOF > "$dummy.c"
		#include <sys/systemcfg.h>

		main()
			{
			if (!__power_pc())
				exit(1);
656
657
658
659
660
661
662
663

664
665
666
667
668
669
670
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688







-
+







			  32) HP_ARCH=hppa2.0n ;;
			  64) HP_ARCH=hppa2.0w ;;
			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
			esac ;;
		    esac
		fi
		if [ "$HP_ARCH" = "" ]; then
		    eval "$set_cc_for_build"
		    set_cc_for_build
		    sed 's/^		//' << EOF > "$dummy.c"

		#define _HPUX_SOURCE
		#include <stdlib.h>
		#include <unistd.h>

		int main ()
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
714
715
716
717
718
719
720

721
722
723
724
725
726
727
728







-
+







EOF
		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
		    test -z "$HP_ARCH" && HP_ARCH=hppa
		fi ;;
	esac
	if [ "$HP_ARCH" = hppa2.0w ]
	then
	    eval "$set_cc_for_build"
	    set_cc_for_build

	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
	    # generating 64-bit code.  GNU and HP use different nomenclature:
	    #
	    # $ CC_FOR_BUILD=cc ./config.guess
	    # => hppa2.0w-hp-hpux11.23
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
740
741
742
743
744
745
746

747
748
749
750
751
752
753
754







-
+







	echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
	exit ;;
    ia64:HP-UX:*:*)
	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
	echo ia64-hp-hpux"$HPUX_REV"
	exit ;;
    3050*:HI-UX:*:*)
	eval "$set_cc_for_build"
	set_cc_for_build
	sed 's/^	//' << EOF > "$dummy.c"
	#include <unistd.h>
	int
	main ()
	{
	  long cpu = sysconf (_SC_CPU_VERSION);
	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
835
836
837
838
839
840
841











842
843
844
845
846
847
848
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







+
+
+
+
+
+
+
+
+
+
+







	echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
	exit ;;
    sparc*:BSD/OS:*:*)
	echo sparc-unknown-bsdi"$UNAME_RELEASE"
	exit ;;
    *:BSD/OS:*:*)
	echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
	exit ;;
    arm:FreeBSD:*:*)
	UNAME_PROCESSOR=`uname -p`
	set_cc_for_build
	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
	    | grep -q __ARM_PCS_VFP
	then
	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi
	else
	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf
	fi
	exit ;;
    *:FreeBSD:*:*)
	UNAME_PROCESSOR=`/usr/bin/uname -p`
	case "$UNAME_PROCESSOR" in
	    amd64)
		UNAME_PROCESSOR=x86_64 ;;
	    i386)
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
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







-
+












-
-
+
+







		echo ia64-unknown-interix"$UNAME_RELEASE"
		exit ;;
	esac ;;
    i*:UWIN*:*)
	echo "$UNAME_MACHINE"-pc-uwin
	exit ;;
    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
	echo x86_64-unknown-cygwin
	echo x86_64-pc-cygwin
	exit ;;
    prep*:SunOS:5.*:*)
	echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
	exit ;;
    *:GNU:*:*)
	# the GNU system
	echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
	exit ;;
    *:GNU/*:*:*)
	# other systems with GNU libc and userland
	echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
	exit ;;
    i*86:Minix:*:*)
	echo "$UNAME_MACHINE"-pc-minix
    *:Minix:*:*)
	echo "$UNAME_MACHINE"-unknown-minix
	exit ;;
    aarch64:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    aarch64_be:Linux:*:*)
	UNAME_MACHINE=aarch64_be
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
947
948
949
950
951
952
953

954
955
956
957
958
959
960
961







-
+







	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    arc:Linux:*:* | arceb:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    arm*:Linux:*:*)
	eval "$set_cc_for_build"
	set_cc_for_build
	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
	    | grep -q __ARM_EABI__
	then
	    echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	else
	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
		| grep -q __ARM_PCS_VFP
967
968
969
970
971
972
973
974

975
976
977
978
979
980
981
996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008
1009
1010







-
+







    m32r*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    m68*:Linux:*:*)
	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
	exit ;;
    mips:Linux:*:* | mips64:Linux:*:*)
	eval "$set_cc_for_build"
	set_cc_for_build
	sed 's/^	//' << EOF > "$dummy.c"
	#undef CPU
	#undef ${UNAME_MACHINE}
	#undef ${UNAME_MACHINE}el
	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
	CPU=${UNAME_MACHINE}el
	#else
1281
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323
1324







-
+







	echo powerpc-apple-rhapsody"$UNAME_RELEASE"
	exit ;;
    *:Rhapsody:*:*)
	echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
	exit ;;
    *:Darwin:*:*)
	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
	eval "$set_cc_for_build"
	set_cc_for_build
	if test "$UNAME_PROCESSOR" = unknown ; then
	    UNAME_PROCESSOR=powerpc
	fi
	if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
1354
1355
1356
1357
1358
1359
1360

1361
1362
1363
1364
1365
1366
1367
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397







+







    DS/*:UNIX_System_V:*:*)
	echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
	exit ;;
    *:Plan9:*:*)
	# "uname -m" is not consistent, so use $cputype instead. 386
	# is converted to i386 for consistency with other x86
	# operating systems.
	# shellcheck disable=SC2154
	if test "$cputype" = 386; then
	    UNAME_MACHINE=i386
	else
	    UNAME_MACHINE="$cputype"
	fi
	echo "$UNAME_MACHINE"-unknown-plan9
	exit ;;
1410
1411
1412
1413
1414
1415
1416



1417
1418
1419
1420
1421
1422
1423
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456







+
+
+







	exit ;;
    x86_64:VMkernel:*:*)
	echo "$UNAME_MACHINE"-unknown-esx
	exit ;;
    amd64:Isilon\ OneFS:*:*)
	echo x86_64-unknown-onefs
	exit ;;
    *:Unleashed:*:*)
	echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
	exit ;;
esac

echo "$0: unable to guess system type" >&2

case "$UNAME_MACHINE:$UNAME_SYSTEM" in
    mips:Linux | mips64:Linux)
	# If we got here on MIPS GNU/Linux, output extra information.

Modified build-aux/config.sub from [0f298c8265] to [f6ee861ee1].

1
2
3

4
5

6
7
8
9
10
11
12
1
2

3
4

5
6
7
8
9
10
11
12


-
+

-
+







#! /bin/sh
# Configuration validation subroutine script.
#   Copyright 1992-2018 Free Software Foundation, Inc.
#   Copyright 1992-2019 Free Software Foundation, Inc.

timestamp='2018-03-08'
timestamp='2019-01-05'

# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77







-
+







  -v, --version      print version number, then exit

Report bugs and patches to <config-patches@gnu.org>."

version="\
GNU config.sub ($timestamp)

Copyright 1992-2018 Free Software Foundation, Inc.
Copyright 1992-2019 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."

help="
Try \`$me --help' for more information."

85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112





113
114
115
116
117
118
119
120
121
122























123
124
125
126




127
128
129
130
131
132
133
134
135
136
137
138






































































139
140
141
142
143
144





















145
146
147

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195























































































































































































































196
197
198
199
















200
201
202
203
204
205
206
207
208
209
210
211
212
213































































214
215
216
217
218
219
220
221
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
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

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
470


471
472
473
474

475
476

477
478
479
480

481
482
483
484
485
486
487
488

489
490

491
492

493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540


541
542
543
544
545
546
547

548
549
550

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
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
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
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
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
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
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
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
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
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079


1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102

1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160

1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181

1182
1183

1184
1185

1186
1187

1188
1189
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
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
1343
1344
1345
1346
1347
1348



1349



1350

1351
1352
1353
1354


1355
1356
1357


1358
1359

1360
1361
1362
1363
1364

































1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397





























1398
1399
1400
1401
1402



1403
1404
1405

1406
1407
1408



1409

1410
1411

1412
1413
1414
1415
1416



1417
1418
1419
1420
1421
1422


1423
1424

1425
1426


















1427

1428
1429
1430

1431
1432
1433
1434
1435
1436
1437
1438
1439
1440


1441
1442
1443


1444
1445
1446


1447
1448
1449


1450
1451
1452


1453
1454
1455


1456
1457
1458


1459
1460
1461


1462
1463
1464


1465
1466
1467


1468
1469
1470


1471
1472
1473

1474
1475
1476
1477


1478
1479
1480


1481
1482
1483


1484
1485
1486


1487
1488
1489


1490
1491
1492


1493
1494
1495


1496
1497
1498


1499
1500
1501


1502
1503
1504


1505
1506
1507


1508
1509
1510


1511
1512

1513
1514
1515
1516

1517
1518

1519
1520
1521

1522
1523
1524
1525

1526
1527

1528
1529

1530


1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550

1551
1552

1553
1554
1555

1556
1557
1558

1559
1560
1561

1562
1563
1564

1565
1566
1567

1568
1569
1570

1571



1572
1573

1574
1575
1576

1577
1578
1579

1580
1581
1582

1583
1584
1585
1586

1587
1588
1589

1590
1591
1592

1593
1594
1595

1596
1597
1598

1599
1600
1601

1602
1603
1604

1605
1606
1607

1608
1609
1610

1611
1612
1613

1614
1615
1616

1617
1618
1619

1620
1621
1622

1623
1624
1625

1626
1627
1628

1629
1630
1631

1632
1633
1634

1635
1636
1637

1638
1639
1640

1641
1642
1643

1644
1645
1646

1647
1648
1649

1650
1651
1652

1653
1654
1655

1656
1657
1658

1659
1660
1661

1662
1663
1664

1665
1666
1667

1668
1669
1670

1671
1672
1673

1674
1675
1676

1677
1678
1679

1680
1681
1682

1683
1684
1685

1686
1687
1688

1689
1690
1691

1692
1693
1694

1695
1696
1697

1698
1699
1700

1701
1702
1703

1704
1705
1706

1707
1708
1709

1710
1711
1712

1713
1714
1715

1716



1717
1718

1719
1720
1721
1722
1723
1724
1725

1726
1727

1728
1729

1730
1731
1732

1733
1734
1735

1736
1737
1738

1739
1740
1741

1742
1743
1744

1745
1746
1747

1748
1749
1750

1751
1752
1753

1754
1755
1756

1757
1758
1759

1760
1761



1762

1763
1764
1765

1766
1767
1768

1769
1770
1771

1772
1773
1774

1775
1776
1777

1778
1779
1780

1781
1782
1783

1784
1785
1786

1787
1788
1789

1790
1791
1792
1793
1794
1795
1796
1797

1798
1799
1800
1801
1802
1803
1804
1805
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117










118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140




141
142
143
144












145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214






215
216
217
218
219
220
221
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
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
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
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530


























531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
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
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
709
710
711






712
713
714
715
716
717


718





719
720
721










722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
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
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
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
956
957
958
959
960
961
962
963
964
965



966
967













968
969





970
971
972
973


974
975





976
977
978
979
980
981






982






983
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












































































1036




1037
1038



1039











1040
1041


1042
1043
1044

1045


1046
1047

1048


1049
1050


1051
1052
1053
1054
1055

1056


1057


1058
1059

1060
1061

1062


1063


1064




1065
1066


1067
1068
1069


1070
1071
1072

1073


1074
1075


1076
1077

1078






1079
1080

1081

1082




1083

1084






1085
1086

1087



1088
1089
1090

1091


1092
1093


1094
1095

1096



1097
1098
1099


1100
1101

1102



1103
1104
1105



1106
1107
1108




1109
1110
1111







1112
1113
1114





1115
1116
1117
1118



1119
1120


1121


1122



1123




1124



1125
1126
1127

1128
1129
1130
1131

1132
1133
1134
1135

1136
1137
1138
1139

1140
1141
1142

1143





























































1144































1145







































1146
1147























1148

1149
























































1150





















1151


1152
1153

1154


1155
1156

















































































1157


















































1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
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
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
1343





























1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374



1375
1376
1377
1378
1379

1380
1381
1382
1383
1384
1385
1386

1387
1388

1389
1390
1391



1392
1393
1394
1395





1396
1397
1398

1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419

1420
1421
1422

1423
1424
1425








1426
1427
1428


1429
1430
1431


1432
1433
1434


1435
1436
1437


1438
1439
1440


1441
1442
1443


1444
1445
1446


1447
1448
1449


1450
1451
1452


1453
1454
1455


1456
1457
1458
1459

1460
1461
1462


1463
1464
1465


1466
1467
1468


1469
1470
1471


1472
1473
1474


1475
1476
1477


1478
1479
1480


1481
1482
1483


1484
1485
1486


1487
1488
1489


1490
1491
1492


1493
1494
1495


1496
1497
1498

1499
1500
1501
1502

1503
1504

1505
1506
1507

1508
1509
1510
1511

1512
1513

1514
1515

1516
1517
1518
1519
1520


1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536

1537
1538

1539
1540
1541

1542
1543
1544

1545
1546
1547

1548
1549
1550

1551
1552
1553

1554
1555
1556

1557
1558
1559
1560
1561
1562

1563
1564
1565

1566
1567
1568

1569
1570
1571

1572
1573
1574
1575

1576
1577
1578

1579
1580
1581

1582
1583
1584

1585
1586
1587

1588
1589
1590

1591
1592
1593

1594
1595
1596

1597
1598
1599

1600
1601
1602

1603
1604
1605

1606
1607
1608

1609
1610
1611

1612
1613
1614

1615
1616
1617

1618
1619
1620

1621
1622
1623

1624
1625
1626

1627
1628
1629

1630
1631
1632

1633
1634
1635

1636
1637
1638

1639
1640
1641

1642
1643
1644

1645
1646
1647

1648
1649
1650

1651
1652
1653

1654
1655
1656

1657
1658
1659

1660
1661
1662

1663
1664
1665

1666
1667
1668

1669
1670
1671

1672
1673
1674

1675
1676
1677

1678
1679
1680

1681
1682
1683

1684
1685
1686

1687
1688
1689

1690
1691
1692

1693
1694
1695

1696
1697
1698

1699
1700
1701

1702
1703
1704

1705
1706
1707
1708
1709
1710

1711
1712
1713
1714
1715
1716
1717

1718


1719
1720

1721
1722
1723

1724
1725
1726

1727
1728
1729

1730
1731
1732

1733
1734
1735

1736
1737
1738

1739
1740
1741

1742
1743
1744

1745
1746
1747

1748
1749
1750

1751
1752
1753
1754
1755
1756

1757
1758
1759

1760
1761
1762

1763
1764
1765

1766
1767
1768

1769
1770
1771

1772
1773
1774

1775
1776
1777

1778
1779
1780

1781
1782
1783

1784
1785
1786
1787

1788
1789
1790

1791
1792
1793
1794
1795
1796
1797
1798
1799







-
+




















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

-
+

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

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

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

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


-
+
-
-
-
+
-

-
-
-
-
+
+
+


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

-




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

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

-
-
-
+
+

-
-
-
-
-
+
+

-
-
+
+

-
-
+
+
+

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

-
+
-
-
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
+
+

-
-
-
-

-
+


-
+


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

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+


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


-
-
+
+

-
+
-
-
+

-
+
-
-
+

-
-
+
+
+

+
-
+
-
-

-
-
+
+
-

+
-
+
-
-

-
-
+
-
-
-
-
+

-
-
+
+

-
-
+
+

-
+
-
-
+

-
-
+
+
-

-
-
-
-
-
-
+
+
-

-
+
-
-
-
-
+
-

-
-
-
-
-
-
+
+
-

-
-
-
+
+

-
+
-
-
+

-
-
+
+
-

-
-
-
+
+

-
-
+
+
-

-
-
-
+
+

-
-
-
+
+

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

-
-
-
+
+
-
-
+
-
-

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


+
-
+


+
-
+


+
-
+


+
-
+


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

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

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

-
+
-
-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

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


-
-
+
+
-
+

-
-
+
+







-
+




-
-
-
+
+
+

+
+
+
-
+


-
-
+
+

-
-
+
+

-
+



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




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


-
-
-
+
+
+


-
+



+
+
+
-
+

-
+


-
-
-
+
+
+

-
-
-
-
-
+
+

-
+


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


-
+


-
-
-
-
-
-
-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+


-
+


-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
+



-
+

-
+


-
+



-
+

-
+

-
+

+
+

-
-
















-
+

-
+


-
+


-
+


-
+


-
+


-
+


-
+

+
+
+

-
+


-
+


-
+


-
+



-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+

+
+
+

-
+






-
+
-
-
+

-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


+
+
+
-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+



-



-
+








    --help | --h* | -h )
       echo "$usage"; exit ;;
    -- )     # Stop option processing
       shift; break ;;
    - )	# Use stdin as input.
       break ;;
    -* )
       echo "$me: invalid option $1$help"
       echo "$me: invalid option $1$help" >&2
       exit 1 ;;

    *local*)
       # First pass through any local machine types.
       echo "$1"
       exit ;;

    * )
       break ;;
  esac
done

case $# in
 0) echo "$me: missing argument$help" >&2
    exit 1;;
 1) ;;
 *) echo "$me: too many arguments$help" >&2
    exit 1;;
esac

# Split fields of configuration type
# shellcheck disable=SC2162
IFS="-" read field1 field2 field3 field4 <<EOF
$1
EOF
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
  kopensolaris*-gnu* | cloudabi*-eabi* | \
  storm-chaos* | os2-emx* | rtmk-nova*)
    os=-$maybe_os

# Separate into logical components for further validation
case $1 in
	*-*-*-*-*)
		echo Invalid configuration \`"$1"\': more than four components >&2
		exit 1
		;;
	*-*-*-*)
		basic_machine=$field1-$field2
		os=$field3-$field4
		;;
	*-*-*)
		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
		# parts
		maybe_os=$field2-$field3
		case $maybe_os in
			nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
			| linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
			| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
			| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
			| storm-chaos* | os2-emx* | rtmk-nova*)
				basic_machine=$field1
				os=$maybe_os
    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
    ;;
  android-linux)
    os=-linux-android
				;;
			android-linux)
				basic_machine=$field1-unknown
				os=linux-android
    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
    ;;
  *)
    basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
    if [ "$basic_machine" != "$1" ]
    then os=`echo "$1" | sed 's/.*-/-/'`
    else os=; fi
    ;;
esac

### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work.  We also
				;;
			*)
				basic_machine=$field1-$field2
				os=$field3
				;;
		esac
		;;
	*-*)
		# A lone config we happen to match not fitting any pattern
		case $field1-$field2 in
			decstation-3100)
				basic_machine=mips-dec
				os=
				;;
			*-*)
				# Second component is usually, but not always the OS
				case $field2 in
					# Prevent following clause from handling this valid os
					sun*os*)
						basic_machine=$field1
						os=$field2
						;;
					# Manufacturers
					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
					| unicom* | ibm* | next | hp | isi* | apollo | altos* \
					| convergent* | ncr* | news | 32* | 3600* | 3100* \
					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
					| ultra | tti* | harris | dolphin | highlevel | gould \
					| cbm | ns | masscomp | apple | axis | knuth | cray \
					| microblaze* | sim | cisco \
					| oki | wec | wrs | winbond)
						basic_machine=$field1-$field2
						os=
						;;
					*)
						basic_machine=$field1
						os=$field2
						;;
				esac
			;;
		esac
		;;
	*)
		# Convert single-component short-hands not valid as part of
		# multi-component configurations.
		case $field1 in
			386bsd)
				basic_machine=i386-pc
				os=bsd
				;;
			a29khif)
				basic_machine=a29k-amd
				os=udi
				;;
			adobe68k)
				basic_machine=m68010-adobe
				os=scout
				;;
			alliant)
				basic_machine=fx80-alliant
				os=
				;;
			altos | altos3068)
				basic_machine=m68k-altos
				os=
				;;
			am29k)
				basic_machine=a29k-none
				os=bsd
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
	-sun*os*)
		# Prevent following clause from handling this invalid input.
		;;
				;;
			amdahl)
				basic_machine=580-amdahl
				os=sysv
				;;
			amiga)
				basic_machine=m68k-unknown
				os=
				;;
			amigaos | amigados)
				basic_machine=m68k-unknown
				os=amigaos
				;;
			amigaunix | amix)
				basic_machine=m68k-unknown
				os=sysv4
				;;
			apollo68)
				basic_machine=m68k-apollo
				os=sysv
				;;
	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
			apollo68bsd)
	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
	-apple | -axis | -knuth | -cray | -microblaze*)
		os=
		basic_machine=$1
		;;
	-bluegene*)
		os=-cnk
		;;
	-sim | -cisco | -oki | -wec | -winbond)
		os=
		basic_machine=$1
		;;
	-scout)
		;;
	-wrs)
		os=-vxworks
		basic_machine=$1
		;;
	-chorusos*)
		os=-chorusos
		basic_machine=$1
		;;
	-chorusrdb)
		os=-chorusrdb
		basic_machine=$1
		;;
	-hiux*)
		os=-hiuxwe2
		;;
	-sco6)
		os=-sco5v6
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
	-sco5)
		os=-sco3.2v5
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
	-sco4)
		os=-sco3.2v4
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
	-sco3.2.[4-9]*)
		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
	-sco3.2v[4-9]*)
				basic_machine=m68k-apollo
				os=bsd
				;;
			aros)
				basic_machine=i386-pc
				os=aros
				;;
			aux)
				basic_machine=m68k-apple
				os=aux
				;;
			balance)
				basic_machine=ns32k-sequent
				os=dynix
				;;
			blackfin)
				basic_machine=bfin-unknown
				os=linux
				;;
			cegcc)
				basic_machine=arm-unknown
				os=cegcc
				;;
			convex-c1)
				basic_machine=c1-convex
				os=bsd
				;;
			convex-c2)
				basic_machine=c2-convex
				os=bsd
				;;
			convex-c32)
				basic_machine=c32-convex
				os=bsd
				;;
			convex-c34)
				basic_machine=c34-convex
				os=bsd
				;;
			convex-c38)
				basic_machine=c38-convex
				os=bsd
				;;
			cray)
				basic_machine=j90-cray
				os=unicos
				;;
			crds | unos)
				basic_machine=m68k-crds
				os=
				;;
			da30)
				basic_machine=m68k-da30
				os=
				;;
			decstation | pmax | pmin | dec3100 | decstatn)
				basic_machine=mips-dec
				os=
				;;
			delta88)
				basic_machine=m88k-motorola
				os=sysv3
				;;
			dicos)
				basic_machine=i686-pc
				os=dicos
				;;
			djgpp)
				basic_machine=i586-pc
				os=msdosdjgpp
				;;
			ebmon29k)
				basic_machine=a29k-amd
				os=ebmon
				;;
			es1800 | OSE68k | ose68k | ose | OSE)
				basic_machine=m68k-ericsson
				os=ose
				;;
			gmicro)
				basic_machine=tron-gmicro
				os=sysv
				;;
			go32)
				basic_machine=i386-pc
				os=go32
				;;
			h8300hms)
				basic_machine=h8300-hitachi
				os=hms
				;;
			h8300xray)
				basic_machine=h8300-hitachi
				os=xray
				;;
			h8500hms)
				basic_machine=h8500-hitachi
				os=hms
				;;
			harris)
				basic_machine=m88k-harris
				os=sysv3
				;;
			hp300)
				basic_machine=m68k-hp
				;;
			hp300bsd)
				basic_machine=m68k-hp
				os=bsd
				;;
			hp300hpux)
				basic_machine=m68k-hp
				os=hpux
				;;
			hppaosf)
				basic_machine=hppa1.1-hp
				os=osf
				;;
			hppro)
				basic_machine=hppa1.1-hp
				os=proelf
				;;
			i386mach)
				basic_machine=i386-mach
				os=mach
				;;
			vsta)
				basic_machine=i386-pc
				os=vsta
				;;
			isi68 | isi)
				basic_machine=m68k-isi
				os=sysv
				;;
			m68knommu)
				basic_machine=m68k-unknown
				os=linux
				;;
			magnum | m3230)
				basic_machine=mips-mips
				os=sysv
				;;
			merlin)
				basic_machine=ns32k-utek
				os=sysv
				;;
			mingw64)
				basic_machine=x86_64-pc
				os=mingw64
				;;
			mingw32)
				basic_machine=i686-pc
				os=mingw32
				;;
			mingw32ce)
				basic_machine=arm-unknown
				os=mingw32ce
				;;
			monitor)
				basic_machine=m68k-rom68k
				os=coff
				;;
			morphos)
				basic_machine=powerpc-unknown
				os=morphos
				;;
			moxiebox)
				basic_machine=moxie-unknown
				os=moxiebox
				;;
			msdos)
				basic_machine=i386-pc
				os=msdos
				;;
			msys)
				basic_machine=i686-pc
				os=msys
				;;
			mvs)
				basic_machine=i370-ibm
				os=mvs
				;;
			nacl)
				basic_machine=le32-unknown
				os=nacl
				;;
			ncr3000)
				basic_machine=i486-ncr
				os=sysv4
				;;
			netbsd386)
				basic_machine=i386-pc
				os=netbsd
				;;
			netwinder)
				basic_machine=armv4l-rebel
				os=linux
				;;
			news | news700 | news800 | news900)
				basic_machine=m68k-sony
				os=newsos
				;;
			news1000)
				basic_machine=m68030-sony
				os=newsos
				;;
			necv70)
				basic_machine=v70-nec
				os=sysv
				;;
			nh3000)
				basic_machine=m68k-harris
				os=cxux
				;;
			nh[45]000)
		# Don't forget version if it is 3.2v4 or newer.
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
	-sco5v6*)
				basic_machine=m88k-harris
				os=cxux
				;;
			nindy960)
				basic_machine=i960-intel
				os=nindy
				;;
			mon960)
				basic_machine=i960-intel
				os=mon960
				;;
			nonstopux)
				basic_machine=mips-compaq
				os=nonstopux
				;;
			os400)
		# Don't forget version if it is 3.2v4 or newer.
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
	-sco*)
		os=-sco3.2v2
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
	-udk*)
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
	-isc)
		os=-isc2.2
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
				basic_machine=powerpc-ibm
				os=os400
				;;
			OSE68000 | ose68000)
				basic_machine=m68000-ericsson
				os=ose
				;;
			os68k)
				basic_machine=m68k-none
				os=os68k
				;;
			paragon)
				basic_machine=i860-intel
				os=osf
				;;
			parisc)
				basic_machine=hppa-unknown
				os=linux
				;;
			pw32)
				basic_machine=i586-unknown
				os=pw32
				;;
			rdos | rdos64)
				basic_machine=x86_64-pc
				os=rdos
				;;
			rdos32)
				basic_machine=i386-pc
				os=rdos
				;;
			rom68k)
				basic_machine=m68k-rom68k
				os=coff
				;;
			sa29200)
				basic_machine=a29k-amd
				os=udi
				;;
			sei)
				basic_machine=mips-sei
				os=seiux
				;;
			sequent)
				basic_machine=i386-sequent
				os=
				;;
			sps7)
				basic_machine=m68k-bull
				os=sysv2
				;;
			st2000)
				basic_machine=m68k-tandem
				os=
				;;
			stratus)
				basic_machine=i860-stratus
				os=sysv4
				;;
			sun2)
				basic_machine=m68000-sun
				os=
				;;
	-clix*)
		basic_machine=clipper-intergraph
		;;
	-isc*)
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
		;;
	-lynx*178)
		os=-lynxos178
		;;
	-lynx*5)
		os=-lynxos5
		;;
	-lynx*)
		os=-lynxos
		;;
	-ptx*)
		basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
		;;
	-psos*)
		os=-psos
		;;
	-mint | -mint[0-9]*)
		basic_machine=m68k-atari
		os=-mint
		;;
esac
			sun2os3)
				basic_machine=m68000-sun
				os=sunos3
				;;
			sun2os4)
				basic_machine=m68000-sun
				os=sunos4
				;;
			sun3)
				basic_machine=m68k-sun
				os=
				;;
			sun3os3)
				basic_machine=m68k-sun
				os=sunos3
				;;
			sun3os4)
				basic_machine=m68k-sun
				os=sunos4
				;;
			sun4)
				basic_machine=sparc-sun
				os=
				;;
			sun4os3)
				basic_machine=sparc-sun
				os=sunos3
				;;
			sun4os4)
				basic_machine=sparc-sun
				os=sunos4
				;;
			sun4sol2)
				basic_machine=sparc-sun
				os=solaris2
				;;
			sun386 | sun386i | roadrunner)
				basic_machine=i386-sun
				os=
				;;
			sv1)
				basic_machine=sv1-cray
				os=unicos
				;;
			symmetry)
				basic_machine=i386-sequent
				os=dynix
				;;
			t3e)
				basic_machine=alphaev5-cray
				os=unicos
				;;
			t90)
				basic_machine=t90-cray
				os=unicos
				;;
			toad1)
				basic_machine=pdp10-xkl
				os=tops20
				;;
			tpf)
				basic_machine=s390x-ibm
				os=tpf
				;;
			udi29k)
				basic_machine=a29k-amd
				os=udi
				;;
			ultra3)
				basic_machine=a29k-nyu
				os=sym1
				;;
			v810 | necv810)
				basic_machine=v810-nec
				os=none
				;;
			vaxv)
				basic_machine=vax-dec
				os=sysv
				;;
			vms)
				basic_machine=vax-dec
				os=vms
				;;
			vxworks960)
				basic_machine=i960-wrs
				os=vxworks
				;;
			vxworks68)
				basic_machine=m68k-wrs
				os=vxworks
				;;
			vxworks29k)
				basic_machine=a29k-wrs
				os=vxworks
				;;
			xbox)
				basic_machine=i686-pc
				os=mingw32
				;;
			ymp)
				basic_machine=ymp-cray
				os=unicos
				;;
			*)
				basic_machine=$1
				os=
				;;
		esac
		;;
esac

# Decode aliases for certain CPU-COMPANY combinations.
# Decode 1-component or ad-hoc basic machines
case $basic_machine in
	# Recognize the basic CPU types without company name.
	# Some are omitted here because they have special meanings below.
	# Here we handle the default manufacturer of certain CPU types.  It is in
	# some cases the only manufacturer, in others, it is the most popular.
	1750a | 580 \
	| a29k \
	| aarch64 | aarch64_be | arm64 \
	w89k)
		cpu=hppa1.1
		vendor=winbond
	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
	| am33_2.0 \
	| arc | arceb \
		;;
	op50n)
		cpu=hppa1.1
		vendor=oki
		;;
	op60c)
	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
	| avr | avr32 \
	| ba \
	| be32 | be64 \
	| bfin \
	| c4x | c8051 | clipper \
	| d10v | d30v | dlx | dsp16xx \
	| e2k | epiphany \
	| fido | fr30 | frv | ft32 \
	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
		cpu=hppa1.1
		vendor=oki
		;;
	ibm*)
		cpu=i370
		vendor=ibm
		;;
	orion105)
		cpu=clipper
		vendor=highlevel
		;;
	mac | mpw | mac-mpw)
		cpu=m68k
		vendor=apple
		;;
	pmac | pmac-mpw)
		cpu=powerpc
		vendor=apple
		;;

	# Recognize the various machine names and aliases which stand
	# for a CPU type and a company and sometimes even an OS.
	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
	| hexagon \
	| i370 | i860 | i960 | ia16 | ia64 \
	| ip2k | iq2000 \
	| k1om \
	| le32 | le64 \
	| lm32 \
		cpu=m68000
		vendor=att
		;;
	3b*)
		cpu=we32k
	| m32c | m32r | m32rle | m68000 | m68k | m88k \
	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
	| mips | mipsbe | mipseb | mipsel | mipsle \
	| mips16 \
	| mips64 | mips64el \
	| mips64octeon | mips64octeonel \
	| mips64orion | mips64orionel \
	| mips64r5900 | mips64r5900el \
	| mips64vr | mips64vrel \
	| mips64vr4100 | mips64vr4100el \
	| mips64vr4300 | mips64vr4300el \
	| mips64vr5000 | mips64vr5000el \
		vendor=att
		;;
	bluegene*)
		cpu=powerpc
		vendor=ibm
		os=cnk
		;;
	decsystem10* | dec10*)
		cpu=pdp10
		vendor=dec
		os=tops10
		;;
	decsystem20* | dec20*)
		cpu=pdp10
		vendor=dec
		os=tops20
		;;
	delta | 3300 | motorola-3300 | motorola-delta \
	      | 3300-motorola | delta-motorola)
		cpu=m68k
		vendor=motorola
		;;
	dpx2*)
		cpu=m68k
		vendor=bull
		os=sysv3
		;;
	encore | umax | mmax)
	| mips64vr5900 | mips64vr5900el \
	| mipsisa32 | mipsisa32el \
	| mipsisa32r2 | mipsisa32r2el \
	| mipsisa32r6 | mipsisa32r6el \
	| mipsisa64 | mipsisa64el \
	| mipsisa64r2 | mipsisa64r2el \
		cpu=ns32k
		vendor=encore
		;;
	elxsi)
		cpu=elxsi
		vendor=elxsi
	| mipsisa64r6 | mipsisa64r6el \
	| mipsisa64sb1 | mipsisa64sb1el \
		os=${os:-bsd}
	| mipsisa64sr71k | mipsisa64sr71kel \
	| mipsr5900 | mipsr5900el \
	| mipstx39 | mipstx39el \
	| mn10200 | mn10300 \
	| moxie \
		;;
	fx2800)
		cpu=i860
	| mt \
	| msp430 \
	| nds32 | nds32le | nds32be \
	| nios | nios2 | nios2eb | nios2el \
	| ns16k | ns32k \
	| open8 | or1k | or1knd | or32 \
	| pdp10 | pj | pjl \
	| powerpc | powerpc64 | powerpc64le | powerpcle \
	| pru \
	| pyramid \
		vendor=alliant
		;;
	genix)
		cpu=ns32k
		vendor=ns
		;;
	h3050r* | hiux*)
		cpu=hppa1.1
		vendor=hitachi
		os=hiuxwe2
		;;
	hp3k9[0-9][0-9] | hp9[0-9][0-9])
		cpu=hppa1.0
		vendor=hp
		;;
	hp9k2[0-9][0-9] | hp9k31[0-9])
		cpu=m68000
		vendor=hp
		;;
	hp9k3[2-9][0-9])
		cpu=m68k
		vendor=hp
		;;
	hp9k6[0-9][0-9] | hp6[0-9][0-9])
		cpu=hppa1.0
		vendor=hp
	| riscv32 | riscv64 \
	| rl78 | rx \
	| score \
		;;
	hp9k7[0-79][0-9] | hp7[0-79][0-9])
		cpu=hppa1.1
		vendor=hp
	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
	| sh64 | sh64le \
		;;
	hp9k78[0-9] | hp78[0-9])
	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
	| spu \
		# FIXME: really hppa2.0-hp
		cpu=hppa1.1
	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
	| ubicom32 \
	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
	| visium \
	| wasm32 \
		vendor=hp
		;;
	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
		# FIXME: really hppa2.0-hp
		cpu=hppa1.1
		vendor=hp
		;;
	hp9k8[0-9][13679] | hp8[0-9][13679])
		cpu=hppa1.1
		vendor=hp
		;;
	hp9k8[0-9][0-9] | hp8[0-9][0-9])
		cpu=hppa1.0
		vendor=hp
		;;
	i*86v32)
	| x86 | xc16x | xstormy16 | xtensa \
	| z8k | z80)
		cpu=`echo "$1" | sed -e 's/86.*/86/'`
		vendor=pc
		os=sysv32
		;;
	i*86v4*)
		basic_machine=$basic_machine-unknown
		cpu=`echo "$1" | sed -e 's/86.*/86/'`
		vendor=pc
		os=sysv4
		;;
	i*86v)
		cpu=`echo "$1" | sed -e 's/86.*/86/'`
		vendor=pc
		os=sysv
		;;
	i*86sol2)
		cpu=`echo "$1" | sed -e 's/86.*/86/'`
		vendor=pc
		os=solaris2
		;;
	j90 | j90-cray)
		cpu=j90
		vendor=cray
		os=${os:-unicos}
		;;
	iris | iris4d)
		cpu=mips
		vendor=sgi
		case $os in
	c54x)
		basic_machine=tic54x-unknown
		    irix*)
			;;
		    *)
			os=irix4
			;;
		esac
		;;
	miniframe)
		cpu=m68000
		vendor=convergent
		;;
	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
		cpu=m68k
		vendor=atari
		os=mint
		;;
	news-3600 | risc-news)
		cpu=mips
		vendor=sony
		os=newsos
		;;
	next | m*-next)
		cpu=m68k
		vendor=next
		case $os in
		    nextstep* )
			;;
		    ns2*)
		      os=nextstep2
			;;
		    *)
		      os=nextstep3
			;;
		esac
		;;
	np1)
		cpu=np1
		vendor=gould
		;;
	op50n-* | op60c-*)
		cpu=hppa1.1
		vendor=oki
		os=proelf
		;;
	pa-hitachi)
		cpu=hppa1.1
		vendor=hitachi
		os=hiuxwe2
		;;
	pbd)
		cpu=sparc
		vendor=tti
		;;
	pbb)
		cpu=m68k
		vendor=tti
		;;
	c55x)
		basic_machine=tic55x-unknown
	pc532)
		cpu=ns32k
		vendor=pc532
		;;
	pn)
		cpu=pn
		vendor=gould
		;;
	power)
		cpu=power
		vendor=ibm
		;;
	ps2)
		cpu=i386
		vendor=ibm
		;;
	psp)
		cpu=mipsallegrexel
		vendor=psp
		;;
	rm[46]00)
		cpu=mips
		vendor=siemens
		;;
	rtpc | rtpc-*)
		cpu=romp
		vendor=ibm
		;;
	sde)
		cpu=mipsisa32
		vendor=sde
		os=${os:-elf}
		;;
	simso-wrs)
		cpu=sparclite
		vendor=wrs
		os=vxworks
		;;
	tower | tower-32)
		cpu=m68k
		vendor=ncr
		;;
	vpp*|vx|vx-*)
		cpu=f301
		vendor=fujitsu
		;;
	c6x)
		basic_machine=tic6x-unknown
	w65)
		cpu=w65
		vendor=wdc
		;;
	w89k-*)
		cpu=hppa1.1
		vendor=winbond
		os=proelf
		;;
	none)
		cpu=none
		vendor=none
		;;
	leon|leon[3-9])
		basic_machine=sparc-$basic_machine
		cpu=sparc
		;;
	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
		basic_machine=$basic_machine-unknown
		vendor=$basic_machine
		os=-none
		;;
	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
		;;
	ms1)
		basic_machine=mt-unknown
	leon-*|leon[3-9]-*)
		cpu=sparc
		vendor=`echo "$basic_machine" | sed 's/-.*//'`
		;;

	strongarm | thumb | xscale)
		basic_machine=arm-unknown
		;;
	xgate)
		basic_machine=$basic_machine-unknown
		os=-none
	*-*)
		;;
	xscaleeb)
		# shellcheck disable=SC2162
		basic_machine=armeb-unknown
		;;

		IFS="-" read cpu vendor <<EOF
	xscaleel)
		basic_machine=armel-unknown
$basic_machine
EOF
		;;

	# We use `pc' rather than `unknown'
	# because (1) that's what they normally are, and
	# (2) the word "unknown" tends to confuse beginning users.
	i*86 | x86_64)
	  basic_machine=$basic_machine-pc
	  ;;
		cpu=$basic_machine
		vendor=pc
		;;
	# Object if more than one company name word.
	*-*-*)
		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
		exit 1
	# These rules are duplicated from below for sake of the special case above;
	# i.e. things that normalized to x86 arches should also default to "pc"
	pc98)
		cpu=i386
		vendor=pc
		;;
	x64 | amd64)
		cpu=x86_64
		vendor=pc
		;;
	# Recognize the basic CPU types with company name.
	580-* \
	# Recognize the basic CPU types without company name.
	*)
	| a29k-* \
	| aarch64-* | aarch64_be-* | arm64-* \
	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
	| avr-* | avr32-* \
	| ba-* \
		cpu=$basic_machine
	| be32-* | be64-* \
	| bfin-* | bs2000-* \
	| c[123]* | c30-* | [cjt]90-* | c4x-* \
	| c8051-* | clipper-* | craynv-* | cydra-* \
	| d10v-* | d30v-* | dlx-* \
	| e2k-* | elxsi-* \
	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
	| h8300-* | h8500-* \
	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
	| hexagon-* \
		vendor=unknown
		;;
esac
	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
	| ip2k-* | iq2000-* \
	| k1om-* \
	| le32-* | le64-* \
	| lm32-* \
	| m32c-* | m32r-* | m32rle-* \
	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
	| microblaze-* | microblazeel-* \
	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
	| mips16-* \
	| mips64-* | mips64el-* \
	| mips64octeon-* | mips64octeonel-* \
	| mips64orion-* | mips64orionel-* \
	| mips64r5900-* | mips64r5900el-* \
	| mips64vr-* | mips64vrel-* \
	| mips64vr4100-* | mips64vr4100el-* \

unset -v basic_machine

# Decode basic machines in the full and proper CPU-Company form.
case $cpu-$vendor in
	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in
	# some cases the only manufacturer, in others, it is the most popular.
	craynv-unknown)
		vendor=cray
		os=${os:-unicosmp}
		;;
	c90-unknown | c90-cray)
	| mips64vr4300-* | mips64vr4300el-* \
	| mips64vr5000-* | mips64vr5000el-* \
	| mips64vr5900-* | mips64vr5900el-* \
		vendor=cray
		os=${os:-unicos}
	| mipsisa32-* | mipsisa32el-* \
	| mipsisa32r2-* | mipsisa32r2el-* \
	| mipsisa32r6-* | mipsisa32r6el-* \
	| mipsisa64-* | mipsisa64el-* \
	| mipsisa64r2-* | mipsisa64r2el-* \
	| mipsisa64r6-* | mipsisa64r6el-* \
	| mipsisa64sb1-* | mipsisa64sb1el-* \
	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
	| mipsr5900-* | mipsr5900el-* \
	| mipstx39-* | mipstx39el-* \
	| mmix-* \
	| mt-* \
	| msp430-* \
		;;
	fx80-unknown)
	| nds32-* | nds32le-* | nds32be-* \
	| nios-* | nios2-* | nios2eb-* | nios2el-* \
	| none-* | np1-* | ns16k-* | ns32k-* \
	| open8-* \
	| or1k*-* \
		vendor=alliant
		;;
	romp-unknown)
		vendor=ibm
	| orion-* \
	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
		;;
	mmix-unknown)
	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
	| pru-* \
	| pyramid-* \
	| riscv32-* | riscv64-* \
	| rl78-* | romp-* | rs6000-* | rx-* \
		vendor=knuth
		;;
	microblaze-unknown | microblazeel-unknown)
		vendor=xilinx
		;;
	rs6000-unknown)
	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
	| sparclite-* \
	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
	| tahoe-* \
		vendor=ibm
	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
	| tile*-* \
	| tron-* \
	| ubicom32-* \
	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
	| vax-* \
		;;
	vax-unknown)
	| visium-* \
	| wasm32-* \
	| we32k-* \
		vendor=dec
		;;
	pdp11-unknown)
		vendor=dec
		;;
	we32k-unknown)
	| x86-* | x86_64-* | xc16x-* | xps100-* \
	| xstormy16-* | xtensa*-* \
		vendor=att
	| ymp-* \
	| z8k-* | z80-*)
		;;
	# Recognize the basic CPU types without company name, with glob match.
	xtensa*)
		basic_machine=$basic_machine-unknown
	cydra-unknown)
		vendor=cydrome
		;;
	# Recognize the various machine names and aliases which stand
	# for a CPU type and a company and sometimes even an OS.
	386bsd)
		basic_machine=i386-pc
		os=-bsd
	i370-ibm*)
		vendor=ibm
		;;
	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
		basic_machine=m68000-att
	orion-unknown)
		vendor=highlevel
		;;
	3b*)
		basic_machine=we32k-att
	xps-unknown | xps100-unknown)
		cpu=xps100
		vendor=honeywell
		;;
	a29khif)
		basic_machine=a29k-amd

	# Here we normalize CPU types with a missing or matching vendor
		os=-udi
		;;
	abacus)
		basic_machine=abacus-unknown
	dpx20-unknown | dpx20-bull)
		;;
	adobe68k)
		cpu=rs6000
		basic_machine=m68010-adobe
		os=-scout
		;;
	alliant | fx80)
		vendor=bull
		basic_machine=fx80-alliant
		;;
	altos | altos3068)
		basic_machine=m68k-altos
		;;
	am29k)
		basic_machine=a29k-none
		os=-bsd
		os=${os:-bosx}
		;;
	amd64)

		basic_machine=x86_64-pc
		;;
	# Here we normalize CPU types irrespective of the vendor
	amd64-*)
		basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		cpu=x86_64
		;;
	amdahl)
		basic_machine=580-amdahl
		os=-sysv
		;;
	amiga | amiga-*)
		basic_machine=m68k-unknown
		;;
	amigaos | amigados)
		basic_machine=m68k-unknown
		os=-amigaos
		;;
	amigaunix | amix)
		basic_machine=m68k-unknown
		os=-sysv4
		;;
	apollo68)
		basic_machine=m68k-apollo
		os=-sysv
		;;
	apollo68bsd)
		basic_machine=m68k-apollo
		os=-bsd
		;;
	aros)
		basic_machine=i386-pc
		os=-aros
		;;
	asmjs)
		basic_machine=asmjs-unknown
		;;
	aux)
		basic_machine=m68k-apple
		os=-aux
		;;
	balance)
		basic_machine=ns32k-sequent
		os=-dynix
		;;
	blackfin)
		basic_machine=bfin-unknown
		os=-linux
		;;
	blackfin-*)
		basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		os=-linux
		cpu=bfin
		os=linux
		;;
	bluegene*)
		basic_machine=powerpc-ibm
		os=-cnk
		;;
	c54x-*)
		basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		cpu=tic54x
		;;
	c55x-*)
		basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		cpu=tic55x
		;;
	c6x-*)
		basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	c90)
		basic_machine=c90-cray
		os=-unicos
		;;
	cegcc)
		basic_machine=arm-unknown
		os=-cegcc
		;;
	convex-c1)
		basic_machine=c1-convex
		os=-bsd
		;;
	convex-c2)
		basic_machine=c2-convex
		os=-bsd
		;;
	convex-c32)
		basic_machine=c32-convex
		os=-bsd
		;;
	convex-c34)
		basic_machine=c34-convex
		os=-bsd
		;;
	convex-c38)
		basic_machine=c38-convex
		os=-bsd
		;;
	cray | j90)
		basic_machine=j90-cray
		os=-unicos
		;;
	craynv)
		basic_machine=craynv-cray
		os=-unicosmp
		;;
	cr16 | cr16-*)
		basic_machine=cr16-unknown
		os=-elf
		;;
	crds | unos)
		basic_machine=m68k-crds
		;;
	crisv32 | crisv32-* | etraxfs*)
		basic_machine=crisv32-axis
		;;
	cris | cris-* | etrax*)
		basic_machine=cris-axis
		;;
	crx)
		basic_machine=crx-unknown
		os=-elf
		;;
	da30 | da30-*)
		basic_machine=m68k-da30
		;;
	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
		basic_machine=mips-dec
		;;
	decsystem10* | dec10*)
		basic_machine=pdp10-dec
		os=-tops10
		;;
	decsystem20* | dec20*)
		basic_machine=pdp10-dec
		os=-tops20
		;;
	delta | 3300 | motorola-3300 | motorola-delta \
	      | 3300-motorola | delta-motorola)
		basic_machine=m68k-motorola
		;;
	delta88)
		basic_machine=m88k-motorola
		os=-sysv3
		;;
	dicos)
		cpu=tic6x
		basic_machine=i686-pc
		os=-dicos
		;;
	djgpp)
		basic_machine=i586-pc
		os=-msdosdjgpp
		;;
	dpx20 | dpx20-*)
		basic_machine=rs6000-bull
		os=-bosx
		;;
	dpx2*)
		basic_machine=m68k-bull
		os=-sysv3
		;;
	e500v[12])
		basic_machine=powerpc-unknown
		os=$os"spe"
		;;
	e500v[12]-*)
		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		cpu=powerpc
		os=$os"spe"
		;;
	ebmon29k)
		basic_machine=a29k-amd
		os=-ebmon
		;;
	elxsi)
		basic_machine=elxsi-elxsi
		os=-bsd
		;;
	encore | umax | mmax)
		basic_machine=ns32k-encore
		;;
	es1800 | OSE68k | ose68k | ose | OSE)
		basic_machine=m68k-ericsson
		os=-ose
		;;
	fx2800)
		basic_machine=i860-alliant
		;;
	genix)
		basic_machine=ns32k-ns
		;;
	gmicro)
		basic_machine=tron-gmicro
		os=-sysv
		;;
	go32)
		basic_machine=i386-pc
		os=-go32
		;;
	h3050r* | hiux*)
		basic_machine=hppa1.1-hitachi
		os=-hiuxwe2
		;;
	h8300hms)
		basic_machine=h8300-hitachi
		os=-hms
		;;
	h8300xray)
		basic_machine=h8300-hitachi
		os=-xray
		;;
	h8500hms)
		basic_machine=h8500-hitachi
		os=-hms
		;;
	harris)
		basic_machine=m88k-harris
		os=-sysv3
		;;
	hp300-*)
	mips3*-*)
		basic_machine=m68k-hp
		;;
	hp300bsd)
		basic_machine=m68k-hp
		os=-bsd
		;;
	hp300hpux)
		basic_machine=m68k-hp
		os=-hpux
		;;
	hp3k9[0-9][0-9] | hp9[0-9][0-9])
		basic_machine=hppa1.0-hp
		;;
	hp9k2[0-9][0-9] | hp9k31[0-9])
		basic_machine=m68000-hp
		;;
	hp9k3[2-9][0-9])
		basic_machine=m68k-hp
		;;
	hp9k6[0-9][0-9] | hp6[0-9][0-9])
		basic_machine=hppa1.0-hp
		;;
	hp9k7[0-79][0-9] | hp7[0-79][0-9])
		basic_machine=hppa1.1-hp
		;;
	hp9k78[0-9] | hp78[0-9])
		# FIXME: really hppa2.0-hp
		basic_machine=hppa1.1-hp
		;;
	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
		# FIXME: really hppa2.0-hp
		basic_machine=hppa1.1-hp
		;;
	hp9k8[0-9][13679] | hp8[0-9][13679])
		basic_machine=hppa1.1-hp
		;;
	hp9k8[0-9][0-9] | hp8[0-9][0-9])
		basic_machine=hppa1.0-hp
		;;
	hppaosf)
		basic_machine=hppa1.1-hp
		os=-osf
		;;
	hppro)
		basic_machine=hppa1.1-hp
		os=-proelf
		;;
	i370-ibm* | ibm*)
		basic_machine=i370-ibm
		;;
	i*86v32)
		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
		os=-sysv32
		;;
	i*86v4*)
		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
		os=-sysv4
		;;
	i*86v)
		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
		os=-sysv
		;;
	i*86sol2)
		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
		os=-solaris2
		;;
	i386mach)
		basic_machine=i386-mach
		os=-mach
		;;
	vsta)
		basic_machine=i386-unknown
		os=-vsta
		;;
	iris | iris4d)
		basic_machine=mips-sgi
		cpu=mips64
		case $os in
		    -irix*)
			;;
		    *)
		;;
	ms1-*)
			os=-irix4
			;;
		esac
		cpu=mt
		;;
	isi68 | isi)
		basic_machine=m68k-isi
		os=-sysv
		;;
	leon-*|leon[3-9]-*)
		basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
		;;
	m68knommu)
		basic_machine=m68k-unknown
		os=-linux
		;;
	m68knommu-*)
		basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		os=-linux
		cpu=m68k
		os=linux
		;;
	magnum | m3230)
	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
		basic_machine=mips-mips
		os=-sysv
		cpu=s12z
		;;
	merlin)
	openrisc-*)
		basic_machine=ns32k-utek
		os=-sysv
		cpu=or32
		;;
	microblaze*)
		basic_machine=microblaze-xilinx
	parisc-*)
		cpu=hppa
		os=linux
		;;
	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
	mingw64)
		cpu=i586
		basic_machine=x86_64-pc
		os=-mingw64
		;;
	mingw32)
		basic_machine=i686-pc
	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
		cpu=i686
		os=-mingw32
		;;
	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
	mingw32ce)
		cpu=i686
		basic_machine=arm-unknown
		os=-mingw32ce
		;;
	miniframe)
		basic_machine=m68000-convergent
	pentium4-*)
		;;
	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
		basic_machine=m68k-atari
		os=-mint
		cpu=i786
		;;
	mips3*-*)
		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
	pc98-*)
		cpu=i386
		;;
	mips3*)
		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
	ppc-* | ppcbe-*)
		cpu=powerpc
		;;
	monitor)
	ppcle-* | powerpclittle-*)
		basic_machine=m68k-rom68k
		os=-coff
		cpu=powerpcle
		;;
	morphos)
		basic_machine=powerpc-unknown
	ppc64-*)
		cpu=powerpc64
		os=-morphos
		;;
	moxiebox)
		basic_machine=moxie-unknown
		os=-moxiebox
		;;
	msdos)
		basic_machine=i386-pc
	ppc64le-* | powerpc64little-*)
		cpu=powerpc64le
		os=-msdos
		;;
	ms1-*)
	sb1-*)
		basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
		;;
	msys)
		basic_machine=i686-pc
		cpu=mipsisa64sb1
		os=-msys
		;;
	mvs)
		basic_machine=i370-ibm
		os=-mvs
		;;
	nacl)
		basic_machine=le32-unknown
	sb1el-*)
		cpu=mipsisa64sb1el
		os=-nacl
		;;
	ncr3000)
		basic_machine=i486-ncr
		os=-sysv4
	sh5e[lb]-*)
		cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
		;;
	netbsd386)
	spur-*)
		basic_machine=i386-unknown
		os=-netbsd
		cpu=spur
		;;
	netwinder)
		basic_machine=armv4l-rebel
	strongarm-* | thumb-*)
		cpu=arm
		os=-linux
		;;
	news | news700 | news800 | news900)
		basic_machine=m68k-sony
		os=-newsos
	tx39-*)
		cpu=mipstx39
		;;
	news1000)
		basic_machine=m68030-sony
	tx39el-*)
		cpu=mipstx39el
		os=-newsos
		;;
	news-3600 | risc-news)
		basic_machine=mips-sony
		os=-newsos
	x64-*)
		cpu=x86_64
		;;
	necv70)
		basic_machine=v70-nec
		os=-sysv
	xscale-* | xscalee[bl]-*)
		cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
		;;
	next | m*-next)
		basic_machine=m68k-next
		case $os in
		    -nextstep* )

	# Recognize the canonical CPU Types that limit and/or modify the
	# company names they are paired with.
			;;
		    -ns2*)
		      os=-nextstep2
			;;
		    *)
		      os=-nextstep3
			;;
	cr16-*)
		os=${os:-elf}
		;;
		esac
		;;
	nh3000)
		basic_machine=m68k-harris
		os=-cxux
	crisv32-* | etraxfs*-*)
		cpu=crisv32
		vendor=axis
		;;
	nh[45]000)
		basic_machine=m88k-harris
		os=-cxux
	cris-* | etrax*-*)
		cpu=cris
		;;
	nindy960)
		vendor=axis
		basic_machine=i960-intel
		os=-nindy
		;;
	mon960)
		basic_machine=i960-intel
		os=-mon960
	crx-*)
		;;
	nonstopux)
		basic_machine=mips-compaq
		os=-nonstopux
		os=${os:-elf}
		;;
	np1)
		basic_machine=np1-gould
		;;
	neo-tandem)
		cpu=neo
		basic_machine=neo-tandem
		vendor=tandem
		;;
	nse-tandem)
		cpu=nse
		basic_machine=nse-tandem
		vendor=tandem
		;;
	nsr-tandem)
		cpu=nsr
		basic_machine=nsr-tandem
		vendor=tandem
		;;
	nsv-tandem)
		cpu=nsv
		basic_machine=nsv-tandem
		vendor=tandem
		;;
	nsx-tandem)
		basic_machine=nsx-tandem
		cpu=nsx
		;;
	op50n-* | op60c-*)
		basic_machine=hppa1.1-oki
		os=-proelf
		;;
	openrisc | openrisc-*)
		basic_machine=or32-unknown
		;;
	os400)
		basic_machine=powerpc-ibm
		os=-os400
		;;
	OSE68000 | ose68000)
		basic_machine=m68000-ericsson
		os=-ose
		;;
	os68k)
		basic_machine=m68k-none
		os=-os68k
		;;
	pa-hitachi)
		basic_machine=hppa1.1-hitachi
		os=-hiuxwe2
		;;
	paragon)
		basic_machine=i860-intel
		os=-osf
		;;
	parisc)
		basic_machine=hppa-unknown
		os=-linux
		;;
	parisc-*)
		basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		os=-linux
		;;
	pbd)
		basic_machine=sparc-tti
		;;
	pbb)
		basic_machine=m68k-tti
		;;
	pc532 | pc532-*)
		basic_machine=ns32k-pc532
		;;
	pc98)
		basic_machine=i386-pc
		;;
	pc98-*)
		basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	pentium | p5 | k5 | k6 | nexgen | viac3)
		basic_machine=i586-pc
		;;
	pentiumpro | p6 | 6x86 | athlon | athlon_*)
		basic_machine=i686-pc
		;;
	pentiumii | pentium2 | pentiumiii | pentium3)
		basic_machine=i686-pc
		;;
	pentium4)
		vendor=tandem
		basic_machine=i786-pc
		;;
	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
		basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	pentiumpro-* | p6-* | 6x86-* | athlon-*)
		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	pentium4-*)
		basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	pn)
		basic_machine=pn-gould
		;;
	power)	basic_machine=power-ibm
		;;
	ppc | ppcbe)	basic_machine=powerpc-unknown
		;;
	ppc-* | ppcbe-*)
		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	ppcle | powerpclittle)
		basic_machine=powerpcle-unknown
		;;
	ppcle-* | powerpclittle-*)
		basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	ppc64)	basic_machine=powerpc64-unknown
		;;
	ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	ppc64le | powerpc64little)
		basic_machine=powerpc64le-unknown
		;;
	ppc64le-* | powerpc64little-*)
		basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	ps2)
		basic_machine=i386-ibm
		;;
	psp)
		basic_machine=mipsallegrexel-psp
		os=-elf
		;;
	pw32)
		basic_machine=i586-unknown
		os=-pw32
		;;
	rdos | rdos64)
		basic_machine=x86_64-pc
		os=-rdos
		;;
	rdos32)
		basic_machine=i386-pc
		os=-rdos
		;;
	rom68k)
		basic_machine=m68k-rom68k
		os=-coff
		;;
	rm[46]00)
		basic_machine=mips-siemens
		;;
	rtpc | rtpc-*)
		basic_machine=romp-ibm
		;;
	s390 | s390-*)
		basic_machine=s390-ibm
	s390-*)
		cpu=s390
		;;
	s390x | s390x-*)
		basic_machine=s390x-ibm
		;;
	sa29200)
		basic_machine=a29k-amd
		os=-udi
		;;
	sb1)
		basic_machine=mipsisa64sb1-unknown
		;;
	sb1el)
		basic_machine=mipsisa64sb1el-unknown
		;;
	sde)
		basic_machine=mipsisa32-sde
		os=-elf
		;;
	sei)
		basic_machine=mips-sei
		os=-seiux
		;;
	sequent)
		vendor=ibm
		basic_machine=i386-sequent
		;;
	sh5el)
		basic_machine=sh5le-unknown
		;;
	simso-wrs)
		basic_machine=sparclite-wrs
		os=-vxworks
		;;
	sps7)
		basic_machine=m68k-bull
		os=-sysv2
		;;
	spur)
		basic_machine=spur-unknown
		;;
	st2000)
		basic_machine=m68k-tandem
		;;
	stratus)
		basic_machine=i860-stratus
		os=-sysv4
		;;
	strongarm-* | thumb-*)
		basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
		;;
	sun2)
		basic_machine=m68000-sun
		;;
	sun2os3)
		basic_machine=m68000-sun
		os=-sunos3
		;;
	sun2os4)
		basic_machine=m68000-sun
		os=-sunos4
		;;
	sun3os3)
		basic_machine=m68k-sun
		os=-sunos3
		;;
	sun3os4)
		basic_machine=m68k-sun
		os=-sunos4
		;;
	sun4os3)
		basic_machine=sparc-sun
		os=-sunos3
		;;
	sun4os4)
		basic_machine=sparc-sun
		os=-sunos4
		;;
	sun4sol2)
		basic_machine=sparc-sun
		os=-solaris2
		;;
	sun3 | sun3-*)
	s390x-*)
		basic_machine=m68k-sun
		;;
	sun4)
		basic_machine=sparc-sun
		;;
	sun386 | sun386i | roadrunner)
		basic_machine=i386-sun
		;;
	sv1)
		basic_machine=sv1-cray
		os=-unicos
		;;
	symmetry)
		basic_machine=i386-sequent
		os=-dynix
		;;
	t3e)
		basic_machine=alphaev5-cray
		os=-unicos
		;;
	t90)
		cpu=s390x
		basic_machine=t90-cray
		os=-unicos
		vendor=ibm
		;;
	tile*)
	tile*-*)
		basic_machine=$basic_machine-unknown
		os=-linux-gnu
		os=${os:-linux-gnu}
		;;
	tx39)
		basic_machine=mipstx39-unknown
		;;
	tx39el)
		basic_machine=mipstx39el-unknown
		;;
	toad1)
		basic_machine=pdp10-xkl
		os=-tops20
		;;
	tower | tower-32)
		basic_machine=m68k-ncr
		;;
	tpf)
		basic_machine=s390x-ibm
		os=-tpf
		;;
	udi29k)
		basic_machine=a29k-amd
		os=-udi
		;;
	ultra3)
		basic_machine=a29k-nyu
		os=-sym1
		;;
	v810 | necv810)
		basic_machine=v810-nec
		os=-none
		;;
	vaxv)
		basic_machine=vax-dec
		os=-sysv
		;;
	vms)
		basic_machine=vax-dec
		os=-vms
		;;
	vpp*|vx|vx-*)
		basic_machine=f301-fujitsu
		;;
	vxworks960)
		basic_machine=i960-wrs
		os=-vxworks
		;;
	vxworks68)
		basic_machine=m68k-wrs
		os=-vxworks
		;;
	vxworks29k)
		basic_machine=a29k-wrs
		os=-vxworks
		;;
	w65*)
		basic_machine=w65-wdc
		os=-none
		;;
	w89k-*)
		basic_machine=hppa1.1-winbond
		os=-proelf
		;;
	x64)
		basic_machine=x86_64-pc
		;;
	xbox)
		basic_machine=i686-pc
		os=-mingw32
		;;
	xps | xps100)
		basic_machine=xps100-honeywell
		;;
	xscale-* | xscalee[bl]-*)
		basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
		;;
	ymp)
		basic_machine=ymp-cray
		os=-unicos
		;;
	none)
		basic_machine=none-none
		os=-none
		;;

# Here we handle the default manufacturer of certain CPU types.  It is in
# some cases the only manufacturer, in others, it is the most popular.
	w89k)
		basic_machine=hppa1.1-winbond
		;;
	op50n)
		basic_machine=hppa1.1-oki
		;;
	op60c)
		basic_machine=hppa1.1-oki
		;;
	romp)
		basic_machine=romp-ibm
		;;
	mmix)
		basic_machine=mmix-knuth
		;;
	rs6000)
		basic_machine=rs6000-ibm
		;;
	vax)
		basic_machine=vax-dec
		;;
	pdp11)
		basic_machine=pdp11-dec
		;;
	we32k)
		basic_machine=we32k-att
		;;
	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
		basic_machine=sh-unknown
		;;
	cydra)
		basic_machine=cydra-cydrome
		;;
	orion)
		basic_machine=orion-highlevel
		;;
	orion105)
		basic_machine=clipper-highlevel
		;;
	mac | mpw | mac-mpw)
		basic_machine=m68k-apple
		;;
	pmac | pmac-mpw)
		basic_machine=powerpc-apple
		;;
	*-unknown)
		# Make sure to match an already-canonicalized machine name.
		;;
	*)
		# Recognize the canonical CPU types that are allowed with any
		# company name.
		case $cpu in
			1750a | 580 \
			| a29k \
			| aarch64 | aarch64_be | arm64 \
			| abacus \
			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
			| alphapca5[67] | alpha64pca5[67] \
			| am33_2.0 \
			| amdgcn \
			| arc | arceb \
			| arm  | arm[lb]e | arme[lb] | armv* \
			| avr | avr32 \
			| asmjs \
			| ba \
			| be32 | be64 \
			| bfin | bs2000 \
			| c[123]* | c30 | [cjt]90 | c4x \
			| c8051 | clipper | craynv | csky | cydra \
			| d10v | d30v | dlx | dsp16xx \
			| e2k | elxsi | epiphany \
			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
			| h8300 | h8500 \
			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
			| hexagon \
			| i370 | i*86 | i860 | i960 | ia16 | ia64 \
			| ip2k | iq2000 \
			| k1om \
			| le32 | le64 \
			| lm32 \
			| m32c | m32r | m32rle \
			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
			| m88110 | m88k | maxq | mb | mcore | mep | metag \
			| microblaze | microblazeel \
			| mips | mipsbe | mipseb | mipsel | mipsle \
			| mips16 \
			| mips64 | mips64eb | mips64el \
			| mips64octeon | mips64octeonel \
			| mips64orion | mips64orionel \
			| mips64r5900 | mips64r5900el \
			| mips64vr | mips64vrel \
			| mips64vr4100 | mips64vr4100el \
			| mips64vr4300 | mips64vr4300el \
			| mips64vr5000 | mips64vr5000el \
			| mips64vr5900 | mips64vr5900el \
			| mipsisa32 | mipsisa32el \
			| mipsisa32r2 | mipsisa32r2el \
			| mipsisa32r6 | mipsisa32r6el \
			| mipsisa64 | mipsisa64el \
			| mipsisa64r2 | mipsisa64r2el \
			| mipsisa64r6 | mipsisa64r6el \
			| mipsisa64sb1 | mipsisa64sb1el \
			| mipsisa64sr71k | mipsisa64sr71kel \
			| mipsr5900 | mipsr5900el \
			| mipstx39 | mipstx39el \
			| mmix \
			| mn10200 | mn10300 \
			| moxie \
			| mt \
			| msp430 \
			| nds32 | nds32le | nds32be \
			| nfp \
			| nios | nios2 | nios2eb | nios2el \
			| none | np1 | ns16k | ns32k | nvptx \
			| open8 \
			| or1k* \
			| or32 \
			| orion \
			| picochip \
			| pdp10 | pdp11 | pj | pjl | pn | power \
			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
			| pru \
			| pyramid \
			| riscv | riscv32 | riscv64 \
			| rl78 | romp | rs6000 | rx \
			| score \
			| sh | shl \
			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
			| sparclite \
			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
			| spu \
			| tahoe \
			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
			| tron \
			| ubicom32 \
			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
			| vax \
			| visium \
			| w65 | wasm32 \
			| we32k \
			| x86 | x86_64 | xc16x | xgate | xps100 \
			| xstormy16 | xtensa* \
			| ymp \
			| z8k | z80)
				;;

			*)
		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
		exit 1
		;;
esac
				echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
				exit 1
				;;
		esac
		;;
esac

# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
	*-digital*)
case $vendor in
	digital*)
		basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
		vendor=dec
		;;
	*-commodore*)
		basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
	commodore*)
		vendor=cbm
		;;
	*)
		;;
esac

# Decode manufacturer-specific aliases for certain operating systems.

if [ x"$os" != x"" ]
if [ x$os != x ]
then
case $os in
	# First match some system type aliases that might get confused
	# with valid system types.
	# -solaris* is a basic system type, with this one exception.
	-auroraux)
		os=-auroraux
	# solaris* is a basic system type, with this one exception.
	auroraux)
		os=auroraux
		;;
	bluegene*)
		os=cnk
		;;
	-solaris1 | -solaris1.*)
	solaris1 | solaris1.*)
		os=`echo $os | sed -e 's|solaris1|sunos4|'`
		;;
	-solaris)
		os=-solaris2
	solaris)
		os=solaris2
		;;
	-unixware*)
		os=-sysv4.2uw
	unixware*)
		os=sysv4.2uw
		;;
	-gnu/linux*)
	gnu/linux*)
		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
		;;
	# es1800 is here to avoid being matched by es* (a different OS)
	-es1800*)
		os=-ose
	es1800*)
		os=ose
		;;
	# Some version numbers need modification
	chorusos*)
		os=chorusos
		;;
	isc)
		os=isc2.2
		;;
	sco6)
		os=sco5v6
		;;
	sco5)
		os=sco3.2v5
		;;
	sco4)
		os=sco3.2v4
		;;
	sco3.2.[4-9]*)
		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
		;;
	sco3.2v[4-9]* | sco5v6*)
		# Don't forget version if it is 3.2v4 or newer.
		;;
	scout)
		# Don't match below
		;;
	sco*)
		os=sco3.2v2
		;;
	psos*)
		os=psos
		;;
	# Now accept the basic system types.
	# The portable systems comes first.
	# Each alternative MUST end in a * to match a version number.
	# -sysv* is not here because it comes later, after sysvr4.
	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
	      | -sym* | -kopensolaris* | -plan9* \
	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
	      | -aos* | -aros* | -cloudabi* | -sortix* \
	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
	      | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \
	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
	      | -morphos* | -superux* | -rtmk* | -windiss* \
	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
	      | -midnightbsd*)
	# sysv* is not here because it comes later, after sysvr4.
	gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
	     | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
	     | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
	     | sym* | kopensolaris* | plan9* \
	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
	     | aos* | aros* | cloudabi* | sortix* \
	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
	     | knetbsd* | mirbsd* | netbsd* \
	     | bitrig* | openbsd* | solidbsd* | libertybsd* \
	     | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
	     | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
	     | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
	     | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \
	     | chorusrdb* | cegcc* | glidix* \
	     | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
	     | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \
	     | linux-newlib* | linux-musl* | linux-uclibc* \
	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \
	     | interix* | uwin* | mks* | rhapsody* | darwin* \
	     | openstep* | oskit* | conix* | pw32* | nonstopux* \
	     | storm-chaos* | tops10* | tenex* | tops20* | its* \
	     | os2* | vos* | palmos* | uclinux* | nucleus* \
	     | morphos* | superux* | rtmk* | windiss* \
	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \
	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
	     | midnightbsd* | amdhsa* | unleashed* | emscripten*)
	# Remember, each alternative MUST END IN *, to match a version number.
		;;
	-qnx*)
		case $basic_machine in
		    x86-* | i*86-*)
	qnx*)
		case $cpu in
		    x86 | i*86)
			;;
		    *)
			os=-nto$os
			os=nto-$os
			;;
		esac
		;;
	hiux*)
		os=hiuxwe2
		;;
	-nto-qnx*)
	nto-qnx*)
		;;
	-nto*)
	nto*)
		os=`echo $os | sed -e 's|nto|nto-qnx|'`
		;;
	-sim | -xray | -os68k* | -v88r* \
	      | -windows* | -osx | -abug | -netware* | -os9* \
	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
	sim | xray | os68k* | v88r* \
	    | windows* | osx | abug | netware* | os9* \
	    | macos* | mpw* | magic* | mmixware* | mon960* | lnews*)
		;;
	-mac*)
		os=`echo "$os" | sed -e 's|mac|macos|'`
		;;
	-linux-dietlibc)
		os=-linux-dietlibc
	linux-dietlibc)
		os=linux-dietlibc
		;;
	-linux*)
	linux*)
		os=`echo $os | sed -e 's|linux|linux-gnu|'`
		;;
	lynx*178)
		os=lynxos178
		;;
	lynx*5)
		os=lynxos5
		;;
	lynx*)
		os=lynxos
		;;
	mac*)
		os=`echo "$os" | sed -e 's|mac|macos|'`
		;;
	opened*)
		os=openedition
		;;
	os400*)
		os=os400
		;;
	-sunos5*)
	sunos5*)
		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
		;;
	-sunos6*)
	sunos6*)
		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
		;;
	-opened*)
		os=-openedition
		;;
	-os400*)
		os=-os400
		;;
	-wince*)
		os=-wince
	wince*)
		os=wince
		;;
	-utek*)
		os=-bsd
	utek*)
		os=bsd
		;;
	-dynix*)
		os=-bsd
	dynix*)
		os=bsd
		;;
	-acis*)
		os=-aos
	acis*)
		os=aos
		;;
	-atheos*)
		os=-atheos
	atheos*)
		os=atheos
		;;
	-syllable*)
		os=-syllable
	syllable*)
		os=syllable
		;;
	-386bsd)
		os=-bsd
	386bsd)
		os=bsd
		;;
	-ctix* | -uts*)
		os=-sysv
	ctix* | uts*)
		os=sysv
		;;
	-nova*)
		os=-rtmk-nova
	nova*)
		os=rtmk-nova
		;;
	-ns2)
		os=-nextstep2
	ns2)
		os=nextstep2
		;;
	-nsk*)
		os=-nsk
	nsk*)
		os=nsk
		;;
	# Preserve the version number of sinix5.
	-sinix5.*)
	sinix5.*)
		os=`echo $os | sed -e 's|sinix|sysv|'`
		;;
	-sinix*)
		os=-sysv4
	sinix*)
		os=sysv4
		;;
	-tpf*)
		os=-tpf
	tpf*)
		os=tpf
		;;
	-triton*)
		os=-sysv3
	triton*)
		os=sysv3
		;;
	-oss*)
		os=-sysv3
	oss*)
		os=sysv3
		;;
	-svr4*)
		os=-sysv4
	svr4*)
		os=sysv4
		;;
	-svr3)
		os=-sysv3
	svr3)
		os=sysv3
		;;
	-sysvr4)
		os=-sysv4
	sysvr4)
		os=sysv4
		;;
	# This must come after -sysvr4.
	-sysv*)
	# This must come after sysvr4.
	sysv*)
		;;
	-ose*)
		os=-ose
	ose*)
		os=ose
		;;
	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
		os=-mint
	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
		os=mint
		;;
	-zvmoe)
		os=-zvmoe
	zvmoe)
		os=zvmoe
		;;
	-dicos*)
		os=-dicos
	dicos*)
		os=dicos
		;;
	-pikeos*)
	pikeos*)
		# Until real need of OS specific support for
		# particular features comes up, bare metal
		# configurations are quite functional.
		case $basic_machine in
		case $cpu in
		    arm*)
			os=-eabi
			os=eabi
			;;
		    *)
			os=-elf
			os=elf
			;;
		esac
		;;
	-nacl*)
	nacl*)
		;;
	-ios)
	ios)
		;;
	-none)
	none)
		;;
	*-eabi)
		;;
	*)
		# Get rid of the `-' at the beginning of $os.
		os=`echo $os | sed 's/[^-]*-//'`
		echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
		exit 1
		;;
esac
else

# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.

# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system.  Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.

case $basic_machine in
case $cpu-$vendor in
	score-*)
		os=-elf
		os=elf
		;;
	spu-*)
		os=-elf
		os=elf
		;;
	*-acorn)
		os=-riscix1.2
		os=riscix1.2
		;;
	arm*-rebel)
		os=-linux
		os=linux
		;;
	arm*-semi)
		os=-aout
		os=aout
		;;
	c4x-* | tic4x-*)
		os=-coff
		os=coff
		;;
	c8051-*)
		os=-elf
		os=elf
		;;
	clipper-intergraph)
		os=clix
		;;
	hexagon-*)
		os=-elf
		os=elf
		;;
	tic54x-*)
		os=-coff
		os=coff
		;;
	tic55x-*)
		os=-coff
		os=coff
		;;
	tic6x-*)
		os=-coff
		os=coff
		;;
	# This must come before the *-dec entry.
	pdp10-*)
		os=-tops20
		os=tops20
		;;
	pdp11-*)
		os=-none
		os=none
		;;
	*-dec | vax-*)
		os=-ultrix4.2
		os=ultrix4.2
		;;
	m68*-apollo)
		os=-domain
		os=domain
		;;
	i386-sun)
		os=-sunos4.0.2
		os=sunos4.0.2
		;;
	m68000-sun)
		os=-sunos3
		os=sunos3
		;;
	m68*-cisco)
		os=-aout
		os=aout
		;;
	mep-*)
		os=-elf
		os=elf
		;;
	mips*-cisco)
		os=-elf
		os=elf
		;;
	mips*-*)
		os=-elf
		os=elf
		;;
	or32-*)
		os=-coff
		os=coff
		;;
	*-tti)	# must be before sparc entry or we get the wrong os.
		os=-sysv3
		os=sysv3
		;;
	sparc-* | *-sun)
		os=-sunos4.1.1
		os=sunos4.1.1
		;;
	pru-*)
		os=-elf
		os=elf
		;;
	*-be)
		os=-beos
		os=beos
		;;
	*-ibm)
		os=-aix
		os=aix
		;;
	*-knuth)
		os=-mmixware
		os=mmixware
		;;
	*-wec)
		os=-proelf
		os=proelf
		;;
	*-winbond)
		os=-proelf
		os=proelf
		;;
	*-oki)
		os=-proelf
		os=proelf
		;;
	*-hp)
		os=-hpux
		os=hpux
		;;
	*-hitachi)
		os=-hiux
		os=hiux
		;;
	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
		os=-sysv
		os=sysv
		;;
	*-cbm)
		os=-amigaos
		os=amigaos
		;;
	*-dg)
		os=-dgux
		os=dgux
		;;
	*-dolphin)
		os=-sysv3
		os=sysv3
		;;
	m68k-ccur)
		os=-rtu
		os=rtu
		;;
	m88k-omron*)
		os=-luna
		os=luna
		;;
	*-next)
		os=-nextstep
		os=nextstep
		;;
	*-sequent)
		os=-ptx
		os=ptx
		;;
	*-crds)
		os=-unos
		os=unos
		;;
	*-ns)
		os=-genix
		os=genix
		;;
	i370-*)
		os=-mvs
		os=mvs
		;;
	*-gould)
		os=-sysv
		os=sysv
		;;
	*-highlevel)
		os=-bsd
		os=bsd
		;;
	*-encore)
		os=-bsd
		os=bsd
		;;
	*-sgi)
		os=-irix
		os=irix
		;;
	*-siemens)
		os=-sysv4
		os=sysv4
		;;
	*-masscomp)
		os=-rtu
		os=rtu
		;;
	f30[01]-fujitsu | f700-fujitsu)
		os=-uxpv
		os=uxpv
		;;
	*-rom68k)
		os=-coff
		os=coff
		;;
	*-*bug)
		os=-coff
		os=coff
		;;
	*-apple)
		os=-macos
		os=macos
		;;
	*-atari*)
		os=-mint
		os=mint
		;;
	*-wrs)
		os=vxworks
		;;
	*)
		os=-none
		os=none
		;;
esac
fi

# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer.  We pick the logical manufacturer.
vendor=unknown
case $vendor in
case $basic_machine in
	*-unknown)
	unknown)
		case $os in
			-riscix*)
			riscix*)
				vendor=acorn
				;;
			-sunos*)
			sunos*)
				vendor=sun
				;;
			-cnk*|-aix*)
			cnk*|-aix*)
				vendor=ibm
				;;
			-beos*)
			beos*)
				vendor=be
				;;
			-hpux*)
			hpux*)
				vendor=hp
				;;
			-mpeix*)
			mpeix*)
				vendor=hp
				;;
			-hiux*)
			hiux*)
				vendor=hitachi
				;;
			-unos*)
			unos*)
				vendor=crds
				;;
			-dgux*)
			dgux*)
				vendor=dg
				;;
			-luna*)
			luna*)
				vendor=omron
				;;
			-genix*)
			genix*)
				vendor=ns
				;;
			clix*)
				vendor=intergraph
				;;
			-mvs* | -opened*)
			mvs* | opened*)
				vendor=ibm
				;;
			-os400*)
			os400*)
				vendor=ibm
				;;
			-ptx*)
			ptx*)
				vendor=sequent
				;;
			-tpf*)
			tpf*)
				vendor=ibm
				;;
			-vxsim* | -vxworks* | -windiss*)
			vxsim* | vxworks* | windiss*)
				vendor=wrs
				;;
			-aux*)
			aux*)
				vendor=apple
				;;
			-hms*)
			hms*)
				vendor=hitachi
				;;
			-mpw* | -macos*)
			mpw* | macos*)
				vendor=apple
				;;
			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
			*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
				vendor=atari
				;;
			-vos*)
			vos*)
				vendor=stratus
				;;
		esac
		basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
		;;
esac

echo "$basic_machine$os"
echo "$cpu-$vendor-$os"
exit

# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:

Modified build-aux/install-sh from [4fa2988af1] to [0170726bd8].

1
2
3
4
5
6







7
8
9
10

11
12
13


14
15
16

17
18
19

20
21
22
23
24
25
26
27
28
29
30
31


32



33
34
35
36
37
38

39
40
41
42
43
44

45
46

47
48
49


50
51
52
53
54

55
56


57
58
59
60
61





62
63
64
65


66
67
68
69
70
71
72






73
74

75

76
77
78
79
80
81





82
83

84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120




121



122

123
124
125
126



127
128
129

130
131
132
133
134
135



136
137
138
139



140

141
142

143
144
145
146
147
148
149
150



151
152
153
154
155


156
157


158
159
160
161
162
163
164




165


166

167
168

169

170
171
172
173
174



175
176
177
178
179
180
181
182






183
184
185
186
187







188
189
190

191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218




219
220
221

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






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




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

1





2
3
4
5
6
7
8


9

10
11


12
13



14



15












16
17

18
19
20
21



22

23
24
25
26
27
28

29


30



31
32
33


34

35

36
37
38





39
40
41
42
43




44
45
46






47
48
49
50
51
52


53

54
55





56
57
58
59
60


61



62























63





64





65
66
67
68
69
70
71
72

73
74



75
76
77



78






79
80
81
82



83
84
85

86
87

88








89
90
91

92



93
94


95
96


97




98
99
100
101
102
103
104

105

106
107

108





109
110
111
112







113
114
115
116
117
118





119
120
121
122
123
124
125



126

127

128

129























130
131
132
133



134







135


136


137
138


139
140
141







142


143
144
145
146

147




148
149
150
151
152
153

154



155
156
157



158
159
160



161
162
163










164






165
166
167
168
169
170
171





172
173
174
175






176
177
178
179


180








181


182








183



184


185


186
187
188
189




190
191
192
193
194
195




196






197
198
199
200
201
202
203
204
205















206
207
208




209
210
211
212
213
214


215



216
217
218

219








220
221



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

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

-
+

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

-
-
-

-
+





-
+
-
-
+
-
-
-
+
+

-
-

-
+
-

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

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

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

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

+
+
+
-
+

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

-
-
-
+
+
+
-
+

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

-
-
-
+
+
-
-
+
+
-
-

-
-
-
-
+
+
+
+

+
+
-
+
-

+
-
+
-
-
-
-
-
+
+
+

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

-
+
-

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


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

-
-
-
+
+
+
-
-
-
+
+

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

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

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

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

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

+
-
+
-
-
-
+
-

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

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

-
+
-
-
+
-
-
-
-
-
-

-
-
-
-
-
-
+

-
-
+
-

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

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

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

-
-
-
+

-
+
-
-
-
-
-
-
+
#!/bin/sh
# install - install a program, script, or datafile

scriptversion=2013-12-25.23; # UTC

# This originates from X11R5 (mit/util/scripts/install.sh), which was
#
# $NetBSD: install-sh.in,v 1.6 2012/01/11 13:07:31 hans Exp $
# This script now also installs multiple files, but might choke on installing
# multiple files with spaces in the file names.
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# the above copyright notice appear in all copies and that both that
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# copyright notice and this permission notice appear in supporting
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# tium.
# written prior permission.  M.I.T. makes no representations about the
# suitability of this software for any purpose.  It is provided "as is"
# without express or implied warranty.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.

tab='	'
# set DOITPROG to echo to test this script
nl='
'

IFS=" $tab$nl"

# Set DOITPROG to "echo" to test this script.
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"

doit=${DOITPROG-}
doit_exec=${doit:-exec}

# Put in absolute file names if you don't have them in your path;
# put in absolute paths if you don't have them in your path; or use env. vars.
# or use environment vars.

awkprog="${AWKPROG-awk}"
mvprog="${MVPROG-mv}"
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"

posix_mkdir=

# Desired mode of installed file.
mode=0755

chgrpcmd=
instcmd="$cpprog"
instflags=""
pathcompchmodcmd="$chmodprog 755"
chmodcmd="$chmodprog 755"
chowncmd=""
chgrpcmd=""
chmodcmd=$chmodprog
chowncmd=
stripcmd=""
mvcmd=$mvprog
stripflags=""
rmcmd="$rmprog -f"
stripcmd=

src=
dst=
dir_arg=
mvcmd="$mvprog"
src=""
msrc=""
dst=""
dir_arg=""
dst_arg=

suffix=""
copy_on_change=false
is_target_a_directory=possibly

suffixfmt=""
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
   or: $0 [OPTION]... SRCFILES... DIRECTORY
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
   or: $0 [OPTION]... -d DIRECTORIES...

In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.

Options:
     --help     display this help and exit.
     --version  display version info and exit.

  -c            (ignored)
  -C            install only if different (preserve the last data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.
  -s            $stripprog installed files.
  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG
"

while [ x"$1" != x ]; do
while test $# -ne 0; do
  case $1 in
    -c) ;;

    -C) copy_on_change=true;;
    case $1 in
	-b) suffix=".old"
	    shift
	    continue;;

	-B) suffixfmt="$2"
	    shift
	    shift
    -d) dir_arg=true;;
	    continue;;

    -g) chgrpcmd="$chgrpprog $2"
        shift;;

	-c) instcmd="$cpprog"
	    shift
	    continue;;
    --help) echo "$usage"; exit $?;;

    -m) mode=$2

        case $mode in
          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
            echo "$0: invalid mode: $mode" >&2
            exit 1;;
        esac
        shift;;
	-d) dir_arg=true
	    shift
	    continue;;

    -o) chowncmd="$chownprog $2"
        shift;;

	-m) chmodcmd="$chmodprog $2"
	    shift
	    shift
    -s) stripcmd=$stripprog;;
	    continue;;

    -t)
	-m*)
        is_target_a_directory=always
        dst_arg=$2
        # Protect names problematic for 'test' and other utilities.
        case $dst_arg in
          -* | [=\(\)!]) dst_arg=./$dst_arg;;
        esac
        shift;;

	    chmodcmd="$chmodprog ${1#-m}"
	    shift
	    continue;;
    -T) is_target_a_directory=never;;

    --version) echo "$0 $scriptversion"; exit $?;;

    --) shift
	-o) chowncmd="$chownprog $2"
	    shift
        break;;

	    shift
	    continue;;
    -*) echo "$0: invalid option: $1" >&2
        exit 1;;

    *)  break;;
  esac
  shift
done
	-g) chgrpcmd="$chgrpprog $2"
	    shift
	    shift
	    continue;;

	-s) stripcmd="$stripprog"
	    shift
# We allow the use of options -d and -T together, by making -d
	    continue;;
# take the precedence; this is for compatibility with GNU install.

	-S) stripcmd="$stripprog"
if test -n "$dir_arg"; then
	    stripflags="-S $2 $stripflags"
  if test -n "$dst_arg"; then
    echo "$0: target directory not allowed when installing a directory." >&2
    exit 1
  fi
fi
	    shift
	    shift
	    continue;;

if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
  # When -d is used, all remaining arguments are directories to create.
  # When -t is used, the destination is already specified.
  # Otherwise, the last argument is the destination.  Remove it from $@.
  for arg
  do
    if test -n "$dst_arg"; then
	-p) instflags="-p"
	    shift
	    continue;;

	*)  if [ x"$msrc" = x ]
	    then
      # $@ is not empty: it contains at least $arg.
      set fnord "$@" "$dst_arg"
      shift # fnord
    fi
    shift # arg
		msrc="$dst"
	    else
		msrc="$msrc $dst"
	    fi
	    src="$dst"
	    dst="$1"
	    shift
    dst_arg=$arg
    # Protect names problematic for 'test' and other utilities.
    case $dst_arg in
	    continue;;
      -* | [=\(\)!]) dst_arg=./$dst_arg;;
    esac
  done
done
fi

if test $# -eq 0; then
  if test -z "$dir_arg"; then
    echo "$0: no input file specified." >&2
    exit 1
  fi
  # It's OK to call 'install-sh -d' without argument.
  # This can happen when creating conditional directories.
  exit 0
fi

if test -z "$dir_arg"; then
  if test $# -gt 1 || test "$is_target_a_directory" = always; then
    if test ! -d "$dst_arg"; then
      echo "$0: $dst_arg: Is not a directory." >&2
      exit 1
    fi
  fi
fi

if test -z "$dir_arg"; then
  do_exit='(exit $ret); exit $ret'
  trap "ret=129; $do_exit" 1
  trap "ret=130; $do_exit" 2
if [ x"$dir_arg" = x ]
then
	dstisfile=""
	if [ ! -d "$dst" ]
  trap "ret=141; $do_exit" 13
  trap "ret=143; $do_exit" 15

	then
  # Set umask so as not to create temps with too-generous modes.
  # However, 'strip' requires both read and write access to temps.
  case $mode in
    # Optimize common cases.
    *644) cp_umask=133;;
    *755) cp_umask=22;;

		if [ x"$msrc" = x"$src" ]
    *[0-7])
      if test -z "$stripcmd"; then
		then
        u_plus_rw=
      else
			dstisfile=true
		else
        u_plus_rw='% 200'
      fi
			echo "install: destination is not a directory"
			exit 1
		fi
      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
    *)
      if test -z "$stripcmd"; then
        u_plus_rw=
      else
        u_plus_rw=,u+rw
      fi
	fi
      cp_umask=$mode$u_plus_rw;;
  esac
else
	msrc="$msrc $dst"
fi

for src
if [ x"$msrc" = x ]
do
  # Protect names problematic for 'test' and other utilities.
  case $src in
    -* | [=\(\)!]) src=./$src;;
then
	echo "install: no destination specified"
	exit 1
fi      

for srcarg in $msrc; do
  esac

  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
if [ x"$dir_arg" != x ]; then

	dstarg="$srcarg"
    test -d "$dstdir"
    dstdir_status=$?
  else
else
	dstarg="$dst"

    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
    # might cause directories to be created, which would be especially bad
    # if $src (and thus $dsttmp) contains '*'.
# Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command
# might cause directories to be created, which would be especially bad 
# if $src (and thus $dsttmp) contains '*'.
    if test ! -f "$src" && test ! -d "$src"; then
      echo "$0: $src does not exist." >&2
      exit 1
    fi

    if test -z "$dst_arg"; then
      echo "$0: no destination specified." >&2
      exit 1
    fi
    dst=$dst_arg

    # If destination is a directory, append the input filename; won't work
    # if double slashes aren't ignored.
    if test -d "$dst"; then
      if test "$is_target_a_directory" = never; then
        echo "$0: $dst_arg: Is a directory" >&2
        exit 1
	if [ -f "$srcarg" ]
	then
		doinst="$instcmd $instflags"
	elif [ -d "$srcarg" ]
	then
		echo "install: $srcarg: not a regular file"
		exit 1
      fi
      dstdir=$dst
      dst=$dstdir/`basename "$src"`
      dstdir_status=0
    else
	elif [ "$srcarg" = "/dev/null" ]
	then
		doinst="$cpprog"
	else
      dstdir=`dirname "$dst"`
      test -d "$dstdir"
      dstdir_status=$?
    fi
  fi

		echo "install:  $srcarg does not exist"
		exit 1
	fi
	
  obsolete_mkdir_used=false

# If destination is a directory, append the input filename; if your system
  if test $dstdir_status != 0; then
    case $posix_mkdir in
      '')
        # Create intermediate dirs using mode 755 as modified by the umask.
        # This is like FreeBSD 'install' as of 1997-10-28.
        umask=`umask`
        case $stripcmd.$umask in
          # Optimize common cases.
# does not like double slashes in filenames, you may need to add some logic
          *[2367][2367]) mkdir_umask=$umask;;
          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;

          *[0-7])
            mkdir_umask=`expr $umask + 22 \
              - $umask % 100 % 40 + $umask % 20 \
              - $umask % 10 % 4 + $umask % 2
            `;;
          *) mkdir_umask=$umask,go-w;;
        esac

	if [ -d "$dstarg" ]
        # With -d, create the new directory with the user-specified mode.
        # Otherwise, rely on $mkdir_umask.
        if test -n "$dir_arg"; then
	then
          mkdir_mode=-m$mode
        else
		dstarg="$dstarg"/`basename "$srcarg"`
          mkdir_mode=
        fi
	fi
fi

## this sed command emulates the dirname command
        posix_mkdir=false
        case $umask in
          *[123567][0-7][0-7])
            # POSIX mkdir -p sets u+wx bits regardless of umask, which
dstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`

# Make sure that the destination directory exists.
#  this part is taken from Noah Friedman's mkinstalldirs script

# Skip lots of stat calls in the usual case.
            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
            ;;
          *)
            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
if [ ! -d "$dstdir" ]; then
            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0

            if (umask $mkdir_umask &&
                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
            then
              if test -z "$dir_arg" || {
defaultIFS='	
'
IFS="${IFS-${defaultIFS}}"

oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
                   # Check for POSIX incompatibilities with -m.
                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
                   # other-writable bit of parent directory when it shouldn't.
                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
                   case $ls_ld_tmpdir in
                     d????-?r-*) different_mode=700;;
                     d????-?--*) different_mode=755;;
                     *) false;;
                   esac &&
                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
                   }
                 }

pathcomp=''

              then posix_mkdir=:
              fi
              rmdir "$tmpdir/d" "$tmpdir"
            else
while [ $# -ne 0 ] ; do
	pathcomp="${pathcomp}${1}"
	shift

	if [ ! -d "${pathcomp}" ] ;
        then
              # Remove any dirs left behind by ancient mkdir implementations.
              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
		$doit $mkdirprog "${pathcomp}"
            fi
            trap '' 0;;
        esac;;
        	if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi &&
        	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi &&
        	if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi
    esac

    if
      $posix_mkdir && (
        umask $mkdir_umask &&
        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
      )
    then :
    else

	else
		true
      # The umask is ridiculous, or mkdir does not conform to POSIX,
      # or it failed possibly due to a race condition.  Create the
      # directory the slow way, step by step, checking for races as we go.
	fi

	pathcomp="${pathcomp}/"
      case $dstdir in
done
        /*) prefix='/';;
        [-=\(\)!]*) prefix='./';;
        *)  prefix='';;
fi
      esac

      oIFS=$IFS
      IFS=/
      set -f
      set fnord $dstdir
      shift
      set +f
	if [ x"$dir_arg" != x ]
	then
		if [ -d "$dstarg" ]; then
			true
		else
      IFS=$oIFS

			$doit $mkdirprog "$dstarg" &&
      prefixes=

      for d
			if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi &&
      do
        test X"$d" = X && continue

			if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi &&
        prefix=$prefix$d
        if test -d "$prefix"; then
          prefixes=
        else
          if $posix_mkdir; then
			if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi
		fi
	else

            (umask=$mkdir_umask &&
             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
		if [ x"$dstisfile" = x ]
            # Don't fail if two instances are running concurrently.
            test -d "$prefix" || exit 1
          else
		then
			file=$srcarg
		else
            case $prefix in
              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
              *) qprefix=$prefix;;
            esac
            prefixes="$prefixes '$qprefix'"
          fi
        fi
			file=$dst
		fi
        prefix=$prefix/
      done

      if test -n "$prefixes"; then
		dstfile=`basename "$file"`
        # Don't fail if two instances are running concurrently.
        (umask $mkdir_umask &&
		dstfinal="$dstdir/$dstfile"
         eval "\$doit_exec \$mkdirprog $prefixes") ||
          test -d "$dstdir" || exit 1
        obsolete_mkdir_used=true
      fi
    fi
  fi

  if test -n "$dir_arg"; then
    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
  else
# Make a temp file name in the proper directory.

    # Make a couple of temp file names in the proper directory.
    dsttmp=$dstdir/_inst.$$_
		dsttmp=$dstdir/#inst.$$#
    rmtmp=$dstdir/_rm.$$_

    # Trap to clean up those temp files at exit.
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0

    # Copy the file name to the temp name.
# Make a backup file name in the proper directory.
		case x$suffixfmt in
		*%*)	suffix=`echo x |
			$awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" '
			{ cnt = 0;
			  do {
				sfx = sprintf(fmt, cnt++);
				name = bname sfx;
    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&

			  } while (system("test -f " name) == 0);
    # and set any options; do chmod last to preserve setuid bits.
    #
    # If any of these fail, we abort the whole thing.  If we want to
    # ignore errors from any of these, just make sure not to ignore
    # errors from the above "$doit $cpprog $src $dsttmp" command.
    #
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
			  print sfx; }' -`;;
		x)	;;
		*)	suffix="$suffixfmt";;
		esac
		dstbackup="$dstfinal$suffix"

# Move or copy the file name to the temp name
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&

    # If -C, don't bother to copy if it wouldn't change the file.
    if $copy_on_change &&
       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
       set -f &&
       set X $old && old=:$2:$4:$5:$6 &&
       set X $new && new=:$2:$4:$5:$6 &&
       set +f &&
       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else
		$doit $doinst $srcarg "$dsttmp" &&

      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
		trap "rm -f ${dsttmp}" 0 &&

# and set any options; do chmod last to preserve setuid bits
      # The rename failed, perhaps because mv can't rename something else

      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
# If any of these fail, we abort the whole thing.  If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.

        # Now remove or move aside any old file at destination location.
        # We try this two ways since rm can't unlink itself on some
        # systems and the destination file might be busy for other
        # reasons.  In this case, the final cleanup might fail but the new
        # file should still install successfully.
        {
          test ! -f "$dst" ||
          $doit $rmcmd -f "$dst" 2>/dev/null ||
		if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi &&
		if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi &&
		if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi &&
		if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi &&

# Now rename the file to the real destination.

		if [ x"$suffix" != x ] && [ -f "$dstfinal" ]
		then
			$doit $mvcmd "$dstfinal" "$dstbackup"
		else
			$doit $rmcmd -f "$dstfinal"
          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
          } ||
          { echo "$0: cannot unlink or rename $dst" >&2
            (exit 1); exit 1
          }
        } &&
		fi &&

        # Now rename the file to the real destination.
        $doit $mvcmd "$dsttmp" "$dst"
		$doit $mvcmd "$dsttmp" "$dstfinal"
      }
    fi || exit 1
	fi

    trap '' 0
  fi
done
done &&

# Local variables:

# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
exit 0

Modified configure.ac from [d8967fc2a8] to [3cdc1802da].

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
14
15
16
17
18
19
20



21
22
23
24
25
26
27







-
-
-







	])
done

BUILDSYS_INIT

AC_CANONICAL_HOST

AC_ARG_WITH(ixemul,
	AS_HELP_STRING([--with-ixemul], [build with ixemul]))

dnl Used to disable checking for -pedantic on some platforms where it's broken
check_pedantic="yes"

case "$host" in
	arm-*-riscos*)
		AS_IF([test x"$OBJCFLAGS" = x""], [
			OBJCFLAGS="-O2 -g"
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
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







+














+
+
-
+
-













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

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

-
+
-
-
-







		AS_IF([test x"$OBJCFLAGS" = x""], [
			OBJCFLAGS="-O0"
		])
		OBJCFLAGS="$OBJCFLAGS -noixemul"
		OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul"
		CPPFLAGS="$CPPFLAGS -D__NO_NET_API"
		LDFLAGS="$LDFLAGS -noixemul"
		LIBS="$LIBS -ldebug"

		enable_files="yes"	# Required for reading ENV:
		enable_shared="no"
		supports_amiga_lib="yes"

		AS_IF([test x"$enable_amiga_lib" != x"no"], [
			AC_SUBST(OBJFWRT_AMIGA_LIB, objfwrt68k.library)
			AC_SUBST(SFDC_TARGET, m68k-amigaos)
			AC_SUBST(SFD_FILE, amigaos3.sfd)
			AC_SUBST(SFDC_INLINE_H, inline.h)
			dnl For 68000, GCC emits calls to helper functions that
			dnl do not work properly in a library.
			t="-mcpu=68020 -fbaserel -noixemul"
			AC_SUBST(AMIGA_LIB_CFLAGS, "$t -ffreestanding")
			t="$t -resident -nostartfiles -nodefaultlibs"
			t="$t -ldebug -lc"
			AC_SUBST(AMIGA_LIB_LDFLAGS,
			AC_SUBST(AMIGA_LIB_LDFLAGS, $t)
				"$t -resident -nostartfiles")
		])

		AC_SUBST(LIBBASES_M, libbases.m)
		;;
	powerpc-*-amigaos*)
		CPPFLAGS="$CPPFLAGS -D__USE_INLINE__"

		enable_files="yes"	# Required for reading ENV:
		enable_shared="no"

		AC_SUBST(LIBBASES_M, libbases.m)
		;;
	*-morphos*)
		AS_IF([test x"$with_ixemul" != x"yes"], [
			AS_IF([test x"$OBJCFLAGS" = x""], [
				OBJCFLAGS="-O2 -g"
			])
			OBJCFLAGS="$OBJCFLAGS -noixemul"
			OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul"
			LDFLAGS="$LDFLAGS -noixemul"
			enable_files="yes"	# Required for reading ENV:
			supports_amiga_lib="yes"
			check_pedantic="no"	# Breaks generated inlines
		AS_IF([test x"$OBJCFLAGS" = x""], [
			OBJCFLAGS="-O2 -g"
		])
		OBJCFLAGS="$OBJCFLAGS -noixemul"
		OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul"
		LDFLAGS="$LDFLAGS -noixemul"
		LIBS="$LIBS -ldebug"

		enable_files="yes"	# Required for reading ENV:
		enable_shared="no"
		supports_amiga_lib="yes"
		check_pedantic="no"	# Breaks generated inlines

			AS_IF([test x"$enable_amiga_lib" != x"no"], [
				AC_SUBST(OBJFWRT_AMIGA_LIB, objfwrt.library)
				AC_SUBST(CVINCLUDE_INLINE_H, inline.h)
				t="-mresident32 -ffreestanding -noixemul"
				AC_SUBST(AMIGA_LIB_CFLAGS, $t)
				t="-mresident32 -nostartfiles -nodefaultlibs"
				t="$t -noixemul -lc"
				AC_SUBST(AMIGA_LIB_LDFLAGS, $t)
			])
		AS_IF([test x"$enable_amiga_lib" != x"no"], [
			AC_SUBST(OBJFWRT_AMIGA_LIB, objfwrt.library)
			AC_SUBST(CVINCLUDE_INLINE_H, inline.h)
			t="-mresident32 -ffreestanding -noixemul"
			AC_SUBST(AMIGA_LIB_CFLAGS, $t)
			t="-mresident32 -nostartfiles -nodefaultlibs"
			t="$t -noixemul -ldebug -lc"
			AC_SUBST(AMIGA_LIB_LDFLAGS, $t)
		])

			AC_SUBST(LIBBASES_M, libbases.m)
		AC_SUBST(LIBBASES_M, libbases.m)
		])

		enable_shared="no"
		;;
	*-msdosdjgpp*)
		enable_shared="no"
		enable_threads="no"
		enable_sockets="no"
		;;
	*-*-mingw*)
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
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
727
728
729
730
731
732
733





























734
735
736
737
738
739
740
741
742
743
744
745


746
747
748
749
750
751
752
753
754
755
756
757
758
759
760

761
762
763
764
765
766
767
768
769







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-












-
-
+













+
-
+
+







AC_C_BIGENDIAN([
	AC_DEFINE(OF_BIG_ENDIAN, 1, [Whether we are big endian])
])
AS_IF([test x"$ac_cv_c_bigendian" = x"universal"], [
	AC_DEFINE(OF_UNIVERSAL, 1, [Whether we are building a universal binary])
])

AC_MSG_CHECKING(for SIZE_MAX)
AC_EGREP_CPP(egrep_cpp_yes, [
	#include <stdint.h>
	#include <limits.h>

	#ifdef SIZE_MAX
	egrep_cpp_yes
	#endif
], [
	AC_MSG_RESULT(yes)
], [
	AC_MSG_RESULT(no)
	AC_MSG_CHECKING(for SIZE_T_MAX)
	AC_EGREP_CPP(egrep_cpp_yes, [
		#include <stdint.h>
		#include <limits.h>

		#ifdef SIZE_T_MAX
		egrep_cpp_yes
		#endif
	], [
		AC_MSG_RESULT(yes)
		size_max="SIZE_T_MAX"
	], [
		AC_MSG_RESULT(no)
		size_max="(~(size_t)0)"
	])
	AC_DEFINE_UNQUOTED(SIZE_MAX, $size_max, [Maximum value for size_t])
])
AC_MSG_CHECKING(for SSIZE_MAX)
AC_EGREP_CPP(egrep_cpp_yes, [
	#include <stdint.h>
	#include <limits.h>

	#ifdef SSIZE_MAX
	egrep_cpp_yes
	#endif
], [
	AC_MSG_RESULT(yes)
], [
	AC_MSG_RESULT(no)
	AC_DEFINE(SSIZE_MAX, [((ssize_t)(SIZE_MAX / 2))],
		[Maximum value for ssize_t])
	AC_DEFINE(SSIZE_MAX, [(SIZE_MAX / 2)], [Maximum value for ssize_t])
])
AC_MSG_CHECKING(for UINTPTR_MAX)
AC_EGREP_CPP(egrep_cpp_yes, [
	#include <stdint.h>
	#include <limits.h>

	#ifdef UINTPTR_MAX
	egrep_cpp_yes
	#endif
], [
	AC_MSG_RESULT(yes)
], [
	AC_MSG_RESULT(no)
	AC_CHECK_SIZEOF(uintptr_t)
	AC_DEFINE(UINTPTR_MAX, [(~(uintptr_t)0)], [Maximum value for uintptr_t])
	AC_DEFINE(UINTPTR_MAX,
		[(SIZEOF_UINTPTR_T * CHAR_BIT)], [Maximum value for uintptr_t])
])

AC_CHECK_HEADER(inttypes.h,
	[AC_DEFINE(OF_HAVE_INTTYPES_H, 1, [Whether we have inttypes.h])])

AC_CHECK_HEADER(sys/types.h,
	[AC_DEFINE(OF_HAVE_SYS_TYPES_H, 1, [Whether we have sys/types.h])])
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
805
806
807
808
809
810
811































812
813
814
815
816
817
818







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	fp_endianess="universal"
])
AC_MSG_RESULT($fp_endianess)
AS_IF([test x"$fp_endianess" = x"unknown"], [
	AC_MSG_ERROR(
		[Floating point implementation does not conform to IEEE 754!])])

AC_MSG_CHECKING(for INFINITY)
AC_COMPILE_IFELSE([
	AC_LANG_PROGRAM([
		#include <stdio.h>
		#include <math.h>
	], [
		printf("%f", INFINITY);
	])
], [
	AC_MSG_RESULT(yes)
], [
	AC_MSG_RESULT(no)

	AC_MSG_CHECKING(for __builtin_inf)
	AC_COMPILE_IFELSE([
		AC_LANG_PROGRAM([
			#include <stdio.h>
		], [
			printf("%f", __builtin_inf());
		])
	], [
		AC_MSG_RESULT(yes)
		AC_DEFINE(INFINITY, [(__builtin_inf())],
			[Workaround for missing INFINITY])
	], [
		AC_MSG_RESULT(no)

		AC_MSG_ERROR([Neither INFINITY or __builtin_inf was found!])
	])
])

case "$host_cpu" in
	arm* | earm*)
		AC_MSG_CHECKING(for VFP2 or above)
		AC_COMPILE_IFELSE([
			AC_LANG_PROGRAM([], [
				#if !defined(__arm64__) && \
				    !defined(__aarch64__) && \
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
887
888
889
890
891
892
893

894
895
896

897
898
899
900
901
902
903







-



-








AS_IF([test x"$ENCODINGS_SRCS" = x""], [
	ENCODINGS_SRCS="dummy.m"
])
AC_SUBST(ENCODINGS_SRCS)
AS_IF([test x"$enable_shared" != x"no"], [
	AC_SUBST(ENCODINGS_LIB_A, "encodings.lib.a")
	AC_SUBST(ENCODINGS_ENCODINGS_LIB_A, "encodings/encodings.lib.a")
])
AS_IF([test x"$enable_static" = x"yes" -o x"$enable_shared" = x"no"], [
	AC_SUBST(ENCODINGS_A, "encodings.a")
	AC_SUBST(ENCODINGS_ENCODINGS_A, "encodings/encodings.a")
])

AC_CHECK_FUNCS(arc4random arc4random_buf getrandom random, break)

AS_IF([test x"$host_os" != x"morphos"], [
	AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl")
])
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813




1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827

1828
1829
1830

1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841

1842
1843
1844
1845
1846
1847
1848
1741
1742
1743
1744
1745
1746
1747



1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764

1765
1766
1767

1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778

1779
1780
1781
1782
1783
1784
1785
1786







-
-
-
+
+
+
+













-
+


-
+










-
+








	old_OBJCFLAGS="$OBJCFLAGS"
	OBJCFLAGS="$OBJCFLAGS -Wunreachable-code"
	AC_MSG_CHECKING(whether -Wunreachable-code can be used)
	AC_COMPILE_IFELSE([
		AC_LANG_SOURCE([[
			#include <stdlib.h>
	
			typedef void *SEL;
	

			struct objc_selector;
			typedef const struct objc_selector *SEL;

			#ifdef __has_attribute
			# if __has_attribute(objc_root_class)
			__attribute__((__objc_root_class__))
			# endif
			#endif
			@interface Object
			- (void)doesNotRecognizeSelector: (SEL)selector
			#ifdef __clang__
			    __attribute__((__noreturn__))
			#endif
			    ;
			- (void)dealloc;
			@end
	

			@interface Foo: Object
			@end
	

			void
			test(void)
			{
				if (sizeof(int) == 4)
					__asm__ ("");
				else if (sizeof(int) == 8)
					__asm__ ("");
				else
					abort();
			}
	

			/*
			 * Unfortunately, this cannot be shorter, as it only
			 * works when it is used inside a macro.
			 */
			#ifdef __clang__
			# define OF_DEALLOC_UNSUPPORTED			\
				[self doesNotRecognizeSelector: _cmd];	\
1857
1858
1859
1860
1861
1862
1863
1864

1865
1866
1867
1868
1869
1870
1871
1795
1796
1797
1798
1799
1800
1801

1802
1803
1804
1805
1806
1807
1808
1809







-
+







			# define OF_DEALLOC_UNSUPPORTED			\
				[self doesNotRecognizeSelector: _cmd];	\
									\
				abort();				\
									\
				[super dealloc];
			#endif
	

			@implementation Foo
			- (void)dealloc
			{
				OF_DEALLOC_UNSUPPORTED
			}
			@end
		]])

Modified src/OFBlock.m from [d3c798f275] to [ada45ac629].

189
190
191
192
193
194
195
196

197
198

199
200
201
202
203
204
205
189
190
191
192
193
194
195

196
197

198
199
200
201
202
203
204
205







-
+

-
+








	if ([(id)block isMemberOfClass: (Class)&_NSConcreteMallocBlock]) {
#ifdef OF_HAVE_ATOMIC_OPS
		of_atomic_int_inc(&block->flags);
#else
		unsigned hash = SPINLOCK_HASH(block);

		OF_ENSURE(of_spinlock_lock(&blockSpinlocks[hash]));
		OF_ENSURE(of_spinlock_lock(&blockSpinlocks[hash]) == 0);
		block->flags++;
		OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]));
		OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]) == 0);
#endif
	}

	return block;
}

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







-
+

-
+








-
+







			block->descriptor->dispose_helper(block);

		free(block);
	}
#else
	unsigned hash = SPINLOCK_HASH(block);

	OF_ENSURE(of_spinlock_lock(&blockSpinlocks[hash]));
	OF_ENSURE(of_spinlock_lock(&blockSpinlocks[hash]) == 0);
	if ((--block->flags & OF_BLOCK_REFCOUNT_MASK) == 0) {
		OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]));
		OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]) == 0);

		if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE)
			block->descriptor->dispose_helper(block);

		free(block);

		return;
	}
	OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]));
	OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]) == 0);
#endif
}

void
_Block_object_assign(void *dst_, const void *src_, const int flags_)
{
	int flags = flags_ & (OF_BLOCK_FIELD_IS_BLOCK |
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
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







-
+








+
-
+









-
+

-
+







				free(*dst);

				*dst = src->forwarding;
			}
#else
			unsigned hash = SPINLOCK_HASH(src);

			OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]));
			OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]) == 0);
			if (src->forwarding == src)
				src->forwarding = *dst;
			else {
				src->byref_dispose(*dst);
				free(*dst);

				*dst = src->forwarding;
			}
			OF_ENSURE(
			OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
			    of_spinlock_unlock(&byrefSpinlocks[hash]) == 0);
#endif
		} else
			*dst = src;

#ifdef OF_HAVE_ATOMIC_OPS
		of_atomic_int_inc(&(*dst)->flags);
#else
		unsigned hash = SPINLOCK_HASH(*dst);

		OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]));
		OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]) == 0);
		(*dst)->flags++;
		OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
		OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]) == 0);
#endif
		break;
	}
}

void
_Block_object_dispose(const void *object_, const int flags_)
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
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







-
+

+
-
+






-
+










-
-
+
+







				object->byref_dispose(object);

			free(object);
		}
#else
		unsigned hash = SPINLOCK_HASH(object);

		OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]));
		OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]) == 0);
		if ((--object->flags & OF_BLOCK_REFCOUNT_MASK) == 0) {
			OF_ENSURE(
			OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
			    of_spinlock_unlock(&byrefSpinlocks[hash]) == 0);

			if (object->flags & OF_BLOCK_HAS_COPY_DISPOSE)
				object->byref_dispose(object);

			free(object);
		}
		OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
		OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]) == 0);
#endif
		break;
	}
}

@implementation OFBlock
+ (void)load
{
#ifndef OF_HAVE_ATOMIC_OPS
	for (size_t i = 0; i < NUM_SPINLOCKS; i++)
		if (!of_spinlock_new(&blockSpinlocks[i]) ||
		    !of_spinlock_new(&byrefSpinlocks[i]))
		if (of_spinlock_new(&blockSpinlocks[i]) != 0 ||
		    of_spinlock_new(&byrefSpinlocks[i]) != 0)
			@throw [OFInitializationFailedException
			    exceptionWithClass: self];
#endif

#ifdef OF_APPLE_RUNTIME
	Class tmp;

Modified src/OFCondition.m from [24791db544] to [53f832df7b].

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
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54


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

70
71
72
73
74

75
76
77
78
79
80

81
82
83
84
85
86

87
88
89
90
91
92







93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109








110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126







-
+













-
-
+
+
+
+











-
+
+
+


-
+





-
+
+
+
+


-
+





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








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







	return [[[self alloc] init] autorelease];
}

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

	if (!of_condition_new(&_condition)) {
	if (of_condition_new(&_condition) != 0) {
		Class c = self.class;
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_conditionInitialized = true;

	return self;
}

- (void)dealloc
{
	if (_conditionInitialized) {
		if (!of_condition_free(&_condition)) {
			OF_ENSURE(errno == EBUSY);
		int error = of_condition_free(&_condition);

		if (error != 0) {
			OF_ENSURE(error == EBUSY);

			@throw [OFConditionStillWaitingException
			    exceptionWithCondition: self];
		}
	}

	[super dealloc];
}

- (void)wait
{
	if (!of_condition_wait(&_condition, &_mutex))
	int error = of_condition_wait(&_condition, &_mutex);

	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: errno];
				     errNo: error];
}

#ifdef OF_AMIGAOS
- (void)waitForConditionOrExecSignal: (ULONG *)signalMask
{
	if (!of_condition_wait_or_signal(&_condition, &_mutex, signalMask))
	int error = of_condition_wait_or_signal(&_condition, &_mutex,
	    signalMask);

	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: errno];
				     errNo: error];
}
#endif

- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval
{
	if (!of_condition_timed_wait(&_condition, &_mutex, timeInterval)) {
		if (errno == ETIMEDOUT)
			return false;
		else
			@throw [OFConditionWaitFailedException
			    exceptionWithCondition: self
					     errNo: errno];
	int error = of_condition_timed_wait(&_condition, &_mutex, timeInterval);

	if (error == ETIMEDOUT)
		return false;

	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: error];
	}

	return true;
}

#ifdef OF_AMIGAOS
- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval
	       orExecSignal: (ULONG *)signalMask
{
	if (!of_condition_timed_wait_or_signal(&_condition, &_mutex,
	    timeInterval, signalMask)) {
		if (errno == ETIMEDOUT)
			return false;
		else
			@throw [OFConditionWaitFailedException
			    exceptionWithCondition: self
					     errNo: errno];
	int error = of_condition_timed_wait_or_signal(&_condition, &_mutex,
	    timeInterval, signalMask);

	if (error == ETIMEDOUT)
		return false;

	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: error];
	}

	return true;
}
#endif

- (bool)waitUntilDate: (OFDate *)date
{
125
126
127
128
129
130
131
132



133
134
135

136
137
138
139
140



141
142
143

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







-
+
+
+


-
+




-
+
+
+


-
+


	return [self waitForTimeInterval: date.timeIntervalSinceNow
			    orExecSignal: signalMask];
}
#endif

- (void)signal
{
	if (!of_condition_signal(&_condition))
	int error = of_condition_signal(&_condition);

	if (error != 0)
		@throw [OFConditionSignalFailedException
		    exceptionWithCondition: self
				     errNo: errno];
				     errNo: error];
}

- (void)broadcast
{
	if (!of_condition_broadcast(&_condition))
	int error = of_condition_broadcast(&_condition);

	if (error != 0)
		@throw [OFConditionBroadcastFailedException
		    exceptionWithCondition: self
				     errNo: errno];
				     errNo: error];
}
@end

Modified src/OFDNSResolverSettings.m from [7c81772fe9] to [d77fb49b97].

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62



63
64
65
66
67
68
69
70
71
72

73

74
75

76



77
78



79

80
81
82
83
84
85
86
87
88

89
90
91
92
93

94
95


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187







+
+
+
+
+
+






-
-
-










-

-
+

-
+
-
-
-


-
-
-

-
+








-
+




-
+

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








#ifdef OF_NINTENDO_3DS
/* Newer versions of libctru started using id as a parameter name. */
# define id id_3ds
# include <3ds.h>
# undef id
#endif

#ifdef OF_MORPHOS
# include <proto/rexxsyslib.h>
# include <rexx/errors.h>
# include <rexx/storage.h>
#endif

#import "socket_helpers.h"

#if defined(OF_HAIKU)
# define HOSTS_PATH @"/system/settings/network/hosts"
# define RESOLV_CONF_PATH @"/system/settings/network/resolv.conf"
#elif defined(OF_MORPHOS)
# define HOSTS_PATH @"ENV:sys/net/hosts"
# define RESOLV_CONF_PATH @"ENV:sys/net/resolv.conf"
#elif defined(OF_AMIGAOS4)
# define HOSTS_PATH @"DEVS:Internet/hosts"
#elif defined(OF_AMIGAOS)
# define HOSTS_PATH @"AmiTCP:db/hosts"
# define RESOLV_CONF_PATH @"AmiTCP:db/resolv.conf"
#else
# define HOSTS_PATH @"/etc/hosts"
# define RESOLV_CONF_PATH @"/etc/resolv.conf"
#endif

#ifndef OF_WII
static OFString *
domainFromHostname(void)
domainFromHostname(OFString *hostname)
{
	char hostname[256];
	if (hostname == nil)
	OFString *domain, *ret;

	if (gethostname(hostname, 256) != 0)
		return nil;

	domain = [OFString stringWithCString: hostname
				    encoding: [OFLocale encoding]];

	@try {
		of_socket_address_parse_ip(domain, 0);
		of_socket_address_parse_ip(hostname, 0);

		/*
		 * If we are still here, the host name is a valid IP address.
		 * We can't use that as local domain.
		 */
		return nil;
	} @catch (OFInvalidFormatException *e) {
		/* Not an IP address -> we can use it if it contains a dot. */
		size_t pos = [domain rangeOfString: @"."].location;
		size_t pos = [hostname rangeOfString: @"."].location;

		if (pos == OF_NOT_FOUND)
			return nil;

		ret = [domain substringFromIndex: pos + 1];
		return [hostname substringFromIndex: pos + 1];
	}

	return ret;
}

#if !defined(OF_WII) && !defined(OF_MORPHOS)
static OFString *
obtainHostname(void)
{
	char hostname[256];

	if (gethostname(hostname, 256) != 0)
		return nil;

	return [OFString stringWithCString: hostname
				  encoding: [OFLocale encoding]];
}
#endif

#ifdef OF_MORPHOS
static OFString *
arexxCommand(const char *port, const char *command)
{
	struct Library *RexxSysBase;
	struct MsgPort *replyPort = NULL;
	struct RexxMsg *msg = NULL;

	if ((RexxSysBase = OpenLibrary("rexxsyslib.library", 36)) == NULL)
		return nil;

	@try {
		struct MsgPort *rexxPort;

		if ((replyPort = CreateMsgPort()) == NULL)
			return nil;

		if ((msg = CreateRexxMsg(replyPort, NULL, port)) == NULL)
			return nil;

		msg->rm_Action = RXCOMM | RXFF_RESULT;

		if ((msg->rm_Args[0] = (char *)CreateArgstring(
		    command, strlen(command))) == NULL)
			return nil;

		Forbid();

		if ((rexxPort = FindPort(port)) == NULL) {
			Permit();
			return nil;
		}

		PutMsg(rexxPort, &msg->rm_Node);
		Permit();
		WaitPort(replyPort);
		GetMsg(replyPort);

		if (msg->rm_Result1 != RC_OK || msg->rm_Result2 == 0)
			return nil;

		return [OFString stringWithCString: (char *)msg->rm_Result2
					  encoding: [OFLocale encoding]];
	} @finally {
		if (msg != NULL) {
			if (msg->rm_Args[0] != NULL)
				DeleteArgstring(msg->rm_Args[0]);
			if (msg->rm_Result2 != 0)
				DeleteArgstring((char *)msg->rm_Result2);

			DeleteRexxMsg(msg);
		}

		if (replyPort != NULL)
			DeleteMsgPort(replyPort);

		CloseLibrary(RexxSysBase);
	}
}

static OFArray OF_GENERIC(OFString *) *
parseNetStackArray(OFString *string)
{
	if (![string hasPrefix: @"["] || ![string hasSuffix: @"]"])
		return nil;

	string = [string substringWithRange: of_range(1, string.length - 2)];

	return [string componentsSeparatedByString: @"|"];
}
#endif

@implementation OFDNSResolverSettings
- (void)dealloc
{
	[_staticHosts release];
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
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







-
+








-
-












-












-
+
-

-






+
-
+









-
+
-
-
-
-
+
-



-
-







#ifndef OF_NINTENDO_3DS
	_configReloadInterval = 2;
#else
	_configReloadInterval = 0;
#endif
}

#if defined(OF_HAVE_FILES) && !defined(OF_NINTENDO_3DS)
#if defined(OF_HAVE_FILES) && !defined(OF_MORPHOS) && !defined(OF_NINTENDO_3DS)
- (void)parseHosts: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFCharacterSet *whitespaceCharacterSet =
	    [OFCharacterSet whitespaceCharacterSet];
	OFMutableDictionary *staticHosts;
	OFFile *file;
	OFString *line;
	OFEnumerator *enumerator;
	OFMutableArray *addresses;

	@try {
		file = [OFFile fileWithPath: path
				       mode: @"r"];
	} @catch (OFOpenItemFailedException *e) {
		objc_autoreleasePoolPop(pool);
		return;
	}

	staticHosts = [OFMutableDictionary dictionary];

	while ((line = [file readLine]) != nil) {
		void *pool2 = objc_autoreleasePoolPush();
		OFArray *components, *hosts;
		size_t pos;
		OFString *address;

		pos = [line rangeOfString: @"#"].location;
		if (pos != OF_NOT_FOUND)
			line = [line substringToIndex: pos];

		components = [line
		    componentsSeparatedByCharactersInSet: whitespaceCharacterSet
						 options: OF_STRING_SKIP_EMPTY];

		if (components.count < 2) {
		if (components.count < 2)
			objc_autoreleasePoolPop(pool2);
			continue;
		}

		address = components.firstObject;
		hosts = [components objectsInRange:
		    of_range(1, components.count - 1)];

		for (OFString *host in hosts) {
			OFMutableArray *addresses =
			addresses = [staticHosts objectForKey: host];
			    [staticHosts objectForKey: host];

			if (addresses == nil) {
				addresses = [OFMutableArray array];
				[staticHosts setObject: addresses
						forKey: host];
			}

			[addresses addObject: address];
		}

	}
		objc_autoreleasePoolPop(pool2);
	}

	enumerator = [staticHosts objectEnumerator];
	for (OFMutableArray *addresses in [staticHosts objectEnumerator])
	while ((addresses = [enumerator nextObject]) != nil)
		[addresses makeImmutable];

	[staticHosts makeImmutable];

	[_staticHosts release];
	_staticHosts = [staticHosts copy];

	objc_autoreleasePoolPop(pool);
}

# if !defined(OF_WINDOWS) && !defined(OF_AMIGAOS4)
- (void)parseResolvConfOption: (OFString *)option
384
385
386
387
388
389
390



















































391
392
393
394
395
396
397
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








	if (fixedInfo->DomainName[0] != '\0')
		_localDomain = [[OFString alloc]
		    initWithCString: fixedInfo->DomainName
			   encoding: encoding];
}
#endif

#ifdef OF_MORPHOS
- (void)obtainMorphOSSystemConfig
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableDictionary *staticHosts;

	_nameServers = [parseNetStackArray(arexxCommand("NETSTACK",
	    "QUERY NAMESERVERS")) copy];
	_localDomain = [domainFromHostname(arexxCommand("NETSTACK",
	    "QUERY HOSTNAME")) copy];
	_searchDomains = [parseNetStackArray(arexxCommand("NETSTACK",
	    "QUERY DOMAINS")) copy];

	staticHosts = [OFMutableDictionary dictionary];

	for (OFString *entry in parseNetStackArray(arexxCommand("NETSTACK",
	    "QUERY HOSTS"))) {
		OFArray *components = [entry componentsSeparatedByString: @" "];
		OFString *address;
		OFArray *hosts;

		if (components.count < 2)
			continue;

		address = components.firstObject;
		hosts = [components objectsInRange:
		    of_range(1, components.count - 1)];

		for (OFString *host in hosts) {
			OFMutableArray *addresses =
			    [staticHosts objectForKey: host];

			if (addresses == nil) {
				addresses = [OFMutableArray array];
				[staticHosts setObject: addresses
						forKey: host];
			}

			[addresses addObject: address];
		}
	}
	for (OFMutableArray *addresses in [staticHosts objectEnumerator])
		[addresses makeImmutable];

	[staticHosts makeImmutable];
	_staticHosts = [staticHosts copy];

	objc_autoreleasePoolPop(pool);
}
#endif

#ifdef OF_AMIGAOS4
- (void)obtainAmigaOS4SystemConfig
{
	OFMutableArray *nameServers = [OFMutableArray array];
	of_string_encoding_t encoding = [OFLocale encoding];
	struct List *nameServerList = ObtainDomainNameServerList();
506
507
508
509
510
511
512


513
514
515
516
517
518
519
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641







+
+







	    stringByExpandingWindowsEnvironmentStrings];

	if (path != nil)
		[self parseHosts: path];
# endif

	[self obtainWindowsSystemConfig];
#elif defined(OF_MORPHOS)
	[self obtainMorphOSSystemConfig];
#elif defined(OF_AMIGAOS4)
	[self parseHosts: HOSTS_PATH];
	[self obtainAmigaOS4SystemConfig];
#elif defined(OF_NINTENDO_3DS)
	[self obtainNintendo3DSSytemConfig];
#elif defined(OF_HAVE_FILES)
	[self parseHosts: HOSTS_PATH];
537
538
539
540
541
542
543
544

545
546

547
548
549
550
551
552
553
554
555
556
557
558
559
659
660
661
662
663
664
665

666
667

668
669
670
671
672
673
674
675
676
677
678
679
680
681







-
+

-
+













#ifdef OF_HAVE_IPV6
		_nameServers = [[OFArray alloc]
		    initWithObjects: @"127.0.0.1", @"::1", nil];
#else
		_nameServers = [[OFArray alloc] initWithObject: @"127.0.0.1"];
#endif

#ifndef OF_WII
#if !defined(OF_WII) && !defined(OF_MORPHOS)
	if (_localDomain == nil)
		_localDomain = [domainFromHostname() copy];
		_localDomain = [domainFromHostname(obtainHostname()) copy];
#endif

	if (_searchDomains == nil) {
		if (_localDomain != nil)
			_searchDomains = [[OFArray alloc]
			    initWithObject: _localDomain];
		else
			_searchDomains = [[OFArray alloc] init];
	}

	objc_autoreleasePoolPop(pool);
}
@end

Modified src/OFDate.m from [2f04475c25] to [d8bff9d62d].

106
107
108
109
110
111
112






113
114
115
116
117
118
119
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125







+
+
+
+
+
+








	return seconds;
}

#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_HAVE_THREADS)
static OFMutex *mutex;

static void
releaseMutex(void)
{
	[mutex release];
}
#endif

#ifdef OF_WINDOWS
static __time64_t (*func__mktime64)(struct tm *);
#endif

#ifdef HAVE_GMTIME_R
342
343
344
345
346
347
348

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







+







		return;

	placeholder.isa = [OFDatePlaceholder class];

#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_HAVE_THREADS)
	mutex = [[OFMutex alloc] init];
	atexit(releaseMutex);
#endif

#ifdef OF_WINDOWS
	if ((module = LoadLibrary("msvcrt.dll")) != NULL)
		func__mktime64 = (__time64_t (*)(struct tm *))
		    GetProcAddress(module, "_mktime64");
#endif

Modified src/OFFileURLHandler.m from [9e0a7e3741] to [7c47454fd6].

81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95







-
+







# include <proto/dos.h>
# include <proto/locale.h>
# ifdef OF_AMIGAOS4
#  define DeleteFile(path) Delete(path)
# endif
#endif

#if defined(OF_WINDOWS) || (defined(OF_AMIGAOS) && !defined(OF_MORPHOS))
#if defined(OF_WINDOWS) || defined(OF_AMIGAOS)
typedef struct {
	of_offset_t st_size;
	unsigned int st_mode;
	of_time_interval_t st_atime, st_mtime, st_ctime;
# ifdef OF_WINDOWS
#  define HAVE_STRUCT_STAT_ST_BIRTHTIME
	of_time_interval_t st_birthtime;
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

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







+
+
+
+
+
+



+
+
+
+
+
+

















-
-
+
+





-
-
+

-
-
+

-
-
+

-
-
+
+
+

-
-




-
-
+
+





-
+
-


-
+
-

-
+
-



-
+
-

-
+
-

-
+
-

-
+
-

-
+
-

-
+
-

-
-
+



















-
+
-
-
+
-















-
+
-
-
+
-



-
+

-
-
+
-




















-
+











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




+

-
-
-
+




+
+
-
+

-


+
+
+
+







#ifdef OF_WINDOWS
# define S_IFLNK 0x10000
# define S_ISLNK(mode) (mode & S_IFLNK)
#endif

#if defined(OF_FILE_MANAGER_SUPPORTS_OWNER) && defined(OF_HAVE_THREADS)
static OFMutex *passwdMutex;

static void
releasePasswdMutex(void)
{
	[passwdMutex release];
}
#endif
#if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) && !defined(OF_WINDOWS)
static OFMutex *readdirMutex;

static void
releaseReaddirMutex(void)
{
	[readdirMutex release];
}
#endif

#ifdef OF_WINDOWS
static int (*func__wutime64)(const wchar_t *, struct __utimbuf64 *);
static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD);
static WINAPI BOOLEAN (*func_CreateHardLinkW)(LPCWSTR, LPCWSTR,
    LPSECURITY_ATTRIBUTES);
#endif

#ifdef OF_WINDOWS
static of_time_interval_t
filetimeToTimeInterval(const FILETIME *filetime)
{
	return (double)((int64_t)filetime->dwHighDateTime << 32 |
	    filetime->dwLowDateTime) / 10000000.0 - 11644473600.0;
}

static void
setErrno(void)
static int
retrieveError(void)
{
	switch (GetLastError()) {
	case ERROR_FILE_NOT_FOUND:
	case ERROR_PATH_NOT_FOUND:
	case ERROR_NO_MORE_FILES:
		errno = ENOENT;
		return;
		return ENOENT;
	case ERROR_ACCESS_DENIED:
		errno = EACCES;
		return;
		return EACCES;
	case ERROR_DIRECTORY:
		errno = ENOTDIR;
		return;
		return ENOTDIR;
	case ERROR_NOT_READY:
		errno = EBUSY;
		return;
		return EBUSY;
	default:
		return EIO;
	}

	errno = 0;
}
#endif

#ifdef OF_AMIGAOS
static void
setErrno(void)
static int
retrieveError(void)
{
	switch (IoErr()) {
	case ERROR_DELETE_PROTECTED:
	case ERROR_READ_PROTECTED:
	case ERROR_WRITE_PROTECTED:
		errno = EACCES;
		return EACCES;
		break;
	case ERROR_DISK_NOT_VALIDATED:
	case ERROR_OBJECT_IN_USE:
		errno = EBUSY;
		return EBUSY;
		break;
	case ERROR_OBJECT_EXISTS:
		errno = EEXIST;
		return EEXIST;
		break;
	case ERROR_DIR_NOT_FOUND:
	case ERROR_NO_MORE_ENTRIES:
	case ERROR_OBJECT_NOT_FOUND:
		errno = ENOENT;
		return ENOENT;
		break;
	case ERROR_NO_FREE_STORE:
		errno = ENOMEM;
		return ENOMEM;
		break;
	case ERROR_DISK_FULL:
		errno = ENOSPC;
		return ENOSPC;
		break;
	case ERROR_DIRECTORY_NOT_EMPTY:
		errno = ENOTEMPTY;
		return ENOTEMPTY;
		break;
	case ERROR_DISK_WRITE_PROTECTED:
		errno = EROFS;
		return EROFS;
		break;
	case ERROR_RENAME_ACROSS_DEVICES:
		errno = EXDEV;
		return EXDEV;
		break;
	default:
		errno = 0;
		break;
		return EIO;
	}
}
#endif

static int
of_stat(OFString *path, of_stat_t *buffer)
{
#if defined(OF_WINDOWS)
	WIN32_FILE_ATTRIBUTE_DATA data;
	bool success;

	if ([OFSystemInfo isWindowsNT])
		success = GetFileAttributesExW(path.UTF16String,
		    GetFileExInfoStandard, &data);
	else
		success = GetFileAttributesExA(
		    [path cStringWithEncoding: [OFLocale encoding]],
		    GetFileExInfoStandard, &data);

	if (!success) {
	if (!success)
		setErrno();
		return -1;
		return retrieveError();
	}

	buffer->st_size = (uint64_t)data.nFileSizeHigh << 32 |
	    data.nFileSizeLow;

	if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		buffer->st_mode = S_IFDIR;
	else if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
		/*
		 * No need to use A functions in this branch: This is only
		 * available on NTFS (and hence Windows NT) anyway.
		 */
		WIN32_FIND_DATAW findData;
		HANDLE findHandle;

		if ((findHandle = FindFirstFileW(path.UTF16String,
		    &findData)) == INVALID_HANDLE_VALUE) {
		    &findData)) == INVALID_HANDLE_VALUE)
			setErrno();
			return -1;
			return retrieveError();
		}

		@try {
			if (!(findData.dwFileAttributes &
			    FILE_ATTRIBUTE_REPARSE_POINT)) {
			    FILE_ATTRIBUTE_REPARSE_POINT))
				/* Race? Indicate to try again. */
				errno = EAGAIN;
				return -1;
				return EAGAIN;
			}

			buffer->st_mode =
			    (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK
			    ? S_IFLNK : S_IFREG);
		} @finally {
			FindClose(findHandle);
		}
	} else
		buffer->st_mode = S_IFREG;

	buffer->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY
	    ? (S_IRUSR | S_IXUSR) : (S_IRUSR | S_IWUSR | S_IXUSR));

	buffer->st_atime = filetimeToTimeInterval(&data.ftLastAccessTime);
	buffer->st_mtime = filetimeToTimeInterval(&data.ftLastWriteTime);
	buffer->st_ctime = buffer->st_birthtime =
	    filetimeToTimeInterval(&data.ftCreationTime);
	buffer->fileAttributes = data.dwFileAttributes;

	return 0;
#elif defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
#elif defined(OF_AMIGAOS)
	BPTR lock;
# ifdef OF_AMIGAOS4
	struct ExamineData *ed;
# else
	struct FileInfoBlock fib;
# endif
	of_time_interval_t timeInterval;
	struct Locale *locale;
	struct DateStamp *date;

	if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]],
	    SHARED_LOCK)) == 0) {
	    SHARED_LOCK)) == 0)
		setErrno();
		return -1;
	}

# ifdef OF_AMIGAOS4
		return retrieveError();

# if defined(OF_MORPHOS)
	if (!Examine64(lock, &fib, TAG_DONE)) {
# elif defined(OF_AMIGAOS4)
	if ((ed = ExamineObjectTags(EX_FileLockInput, lock, TAG_END)) == NULL) {
# else
	if (!Examine(lock, &fib)) {
# endif
		int error = retrieveError();
		UnLock(lock);

		errno = 0;
		return -1;
		return error;
	}

	UnLock(lock);

# if defined(OF_MORPHOS)
	buffer->st_size = fib.fib_Size64;
# ifdef OF_AMIGAOS4
# elif defined(OF_AMIGAOS4)
	buffer->st_size = ed->FileSize;
	buffer->st_mode = (EXD_IS_DIRECTORY(ed) ? S_IFDIR : S_IFREG);
# else
	buffer->st_size = fib.fib_Size;
# endif
# ifdef OF_AMIGAOS4
	buffer->st_mode = (EXD_IS_DIRECTORY(ed) ? S_IFDIR : S_IFREG);
# else
	buffer->st_mode = (fib.fib_DirEntryType > 0 ? S_IFDIR : S_IFREG);
# endif

	timeInterval = 252460800;	/* 1978-01-01 */

	locale = OpenLocale(NULL);
	/*
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
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







-
+
+
+
+
+

-
+
+
+
+









-
+
+
+

-
+
+

+
+








# ifdef OF_AMIGAOS4
	FreeDosObject(DOS_EXAMINEDATA, ed);
# endif

	return 0;
#elif defined(HAVE_STAT64)
	return stat64([path cStringWithEncoding: [OFLocale encoding]], buffer);
	if (stat64([path cStringWithEncoding: [OFLocale encoding]],
	    buffer) != 0)
		return errno;

	return 0;
#else
	return stat([path cStringWithEncoding: [OFLocale encoding]], buffer);
	if (stat([path cStringWithEncoding: [OFLocale encoding]], buffer) != 0)
		return errno;

	return 0;
#endif
}

static int
of_lstat(OFString *path, of_stat_t *buffer)
{
#if defined(HAVE_LSTAT) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS) && \
    !defined(OF_NINTENDO_3DS) && !defined(OF_WII)
# ifdef HAVE_LSTAT64
	return lstat64([path cStringWithEncoding: [OFLocale encoding]], buffer);
	if (lstat64([path cStringWithEncoding: [OFLocale encoding]],
	    buffer) != 0)
		return errno;
# else
	return lstat([path cStringWithEncoding: [OFLocale encoding]], buffer);
	if (lstat([path cStringWithEncoding: [OFLocale encoding]], buffer) != 0)
		return errno;
# endif

	return 0;
#else
	return of_stat(path, buffer);
#endif
}

static void
setTypeAttribute(of_mutable_file_attributes_t attributes, of_stat_t *s)
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
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515

516
517
518
519
520

521
522
523
524
525
526
527
528







-
+















-
+




-
+







		return;

	if ((handle = CreateFileW(path.UTF16String, 0, (FILE_SHARE_READ |
	    FILE_SHARE_WRITE), NULL, OPEN_EXISTING,
	    FILE_FLAG_OPEN_REPARSE_POINT, NULL)) == INVALID_HANDLE_VALUE)
		@throw [OFRetrieveItemAttributesFailedException
		    exceptionWithURL: URL
			       errNo: 0];
			       errNo: retrieveError()];

	@try {
		union {
			char bytes[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
			REPARSE_DATA_BUFFER data;
		} buffer;
		DWORD size;
		wchar_t *tmp;
		of_file_attribute_key_t key;

		if (!DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0,
		    buffer.bytes, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &size,
		    NULL))
			@throw [OFRetrieveItemAttributesFailedException
			    exceptionWithURL: URL
				       errNo: 0];
				       errNo: retrieveError()];

		if (buffer.data.ReparseTag != IO_REPARSE_TAG_SYMLINK)
			@throw [OFRetrieveItemAttributesFailedException
			    exceptionWithURL: URL
				       errNo: 0];
				       errNo: retrieveError()];

#  define slrb buffer.data.SymbolicLinkReparseBuffer
		tmp = slrb.PathBuffer +
		    (slrb.SubstituteNameOffset / sizeof(wchar_t));

		destination = [OFString
		    stringWithUTF16String: tmp
542
543
544
545
546
547
548

549
550
551

552
553
554
555
556
557
558
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568







+



+







#endif

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

#if defined(OF_FILE_MANAGER_SUPPORTS_OWNER) && defined(OF_HAVE_THREADS)
	passwdMutex = [[OFMutex alloc] init];
	atexit(releasePasswdMutex);
#endif
#if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS)
	readdirMutex = [[OFMutex alloc] init];
	atexit(releaseReaddirMutex);
#endif

#ifdef OF_WINDOWS
	if ((module = LoadLibrary("msvcrt.dll")) != NULL)
		func__wutime64 = (int (*)(const wchar_t *,
		    struct __utimbuf64 *))GetProcAddress(module, "_wutime64");

574
575
576
577
578
579
580
581

582
583
584
585
586
587
588
584
585
586
587
588
589
590

591
592
593
594
595
596
597
598







-
+







	[OFFile class];
}

+ (bool)of_directoryExistsAtPath: (OFString *)path
{
	of_stat_t s;

	if (of_stat(path, &s) == -1)
	if (of_stat(path, &s) != 0)
		return false;

	return S_ISDIR(s.st_mode);
}

- (OFStream *)openItemAtURL: (OFURL *)URL
		       mode: (OFString *)mode
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
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







+










-
+


-
+







}

- (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL
{
	of_mutable_file_attributes_t ret = [OFMutableDictionary dictionary];
	void *pool = objc_autoreleasePoolPush();
	OFString *path;
	int error;
	of_stat_t s;

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

	if (![[URL scheme] isEqual: _scheme])
		@throw [OFInvalidArgumentException exception];

	path = URL.fileSystemRepresentation;

	if (of_lstat(path, &s) == -1)
	if ((error = of_lstat(path, &s)) != 0)
		@throw [OFRetrieveItemAttributesFailedException
		    exceptionWithURL: URL
			       errNo: errno];
			       errNo: error];

	if (s.st_size < 0)
		@throw [OFOutOfRangeException exception];

	[ret setObject: [NSNumber numberWithUnsignedLongLong: s.st_size]
		forKey: of_file_attribute_key_size];

714
715
716
717
718
719
720

721
722
723
724






725
726
727
728
729

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




733
734
735
736
737
738
739
740
741
742

743

744
745
746
747
748
749
750







+
-
-
-
-
+
+
+
+
+
+




-
+
-







	modificationTime -= locale->loc_GMTOffset * 60.0;
	CloseLocale(locale);

	date.ds_Days = modificationTime / 86400;
	date.ds_Minute = ((LONG)modificationTime % 86400) / 60;
	date.ds_Tick = fmod(modificationTime, 60) * TICKS_PER_SECOND;

# ifdef OF_AMIGAOS4
	if (!SetFileDate([path cStringWithEncoding: [OFLocale encoding]],
	    &date) != 0) {
		setErrno();

	if (!SetDate([path cStringWithEncoding: [OFLocale encoding]],
	    &date) != 0)
# else
	if (!SetFileDate([path cStringWithEncoding: [OFLocale encoding]],
	    &date) != 0)
# endif
		@throw [OFSetItemAttributesFailedException
		    exceptionWithURL: URL
			  attributes: attributes
		     failedAttribute: attributeKey
			       errNo: errno];
			       errNo: retrieveError()];
	}
#else
	of_time_interval_t lastAccessTime =
	    lastAccessDate.timeIntervalSince1970;
	of_time_interval_t modificationTime =
	    modificationDate.timeIntervalSince1970;
	struct timeval times[2] = {
		{
916
917
918
919
920
921
922
923

924
925
926
927
928
929
930
929
930
931
932
933
934
935

936
937
938
939
940
941
942
943







-
+








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

	if (![URL.scheme isEqual: _scheme])
		@throw [OFInvalidArgumentException exception];

	if (of_stat(URL.fileSystemRepresentation, &s) == -1) {
	if (of_stat(URL.fileSystemRepresentation, &s) != 0) {
		objc_autoreleasePoolPop(pool);
		return false;
	}

	ret = S_ISREG(s.st_mode);

	objc_autoreleasePoolPop(pool);
940
941
942
943
944
945
946
947

948
949
950
951
952
953
954
953
954
955
956
957
958
959

960
961
962
963
964
965
966
967







-
+








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

	if (![URL.scheme isEqual: _scheme])
		@throw [OFInvalidArgumentException exception];

	if (of_stat(URL.fileSystemRepresentation, &s) == -1) {
	if (of_stat(URL.fileSystemRepresentation, &s) != 0) {
		objc_autoreleasePoolPop(pool);
		return false;
	}

	ret = S_ISDIR(s.st_mode);

	objc_autoreleasePoolPop(pool);
982
983
984
985
986
987
988
989

990
991
992
993
994

995
996
997
998
999
1000
1001
1002
995
996
997
998
999
1000
1001

1002


1003
1004

1005

1006
1007
1008
1009
1010
1011
1012







-
+
-
-


-
+
-







		@throw [OFCreateDirectoryFailedException
		    exceptionWithURL: URL
			       errNo: errno];
#elif defined(OF_AMIGAOS)
	BPTR lock;

	if ((lock = CreateDir(
	    [path cStringWithEncoding: [OFLocale encoding]])) == 0) {
	    [path cStringWithEncoding: [OFLocale encoding]])) == 0)
		setErrno();

		@throw [OFCreateDirectoryFailedException
		    exceptionWithURL: URL
			       errNo: errno];
			       errNo: retrieveError()];
	}

	UnLock(lock);
#else
	if (mkdir([path cStringWithEncoding: [OFLocale encoding]], 0777) != 0)
		@throw [OFCreateDirectoryFailedException
		    exceptionWithURL: URL
			       errNo: errno];
1024
1025
1026
1027
1028
1029
1030
1031

1032
1033
1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1048
1034
1035
1036
1037
1038
1039
1040

1041





1042
1043
1044

1045

1046
1047
1048
1049
1050
1051
1052







-
+
-
-
-
-
-



-
+
-








	path = [path stringByAppendingString: @"\\*"];

	if ([OFSystemInfo isWindowsNT]) {
		WIN32_FIND_DATAW fd;

		if ((handle = FindFirstFileW(path.UTF16String,
		    &fd)) == INVALID_HANDLE_VALUE) {
		    &fd)) == INVALID_HANDLE_VALUE)
			int errNo = 0;

			if (GetLastError() == ERROR_FILE_NOT_FOUND)
				errNo = ENOENT;

			@throw [OFOpenItemFailedException
			    exceptionWithURL: URL
					mode: nil
				       errNo: errNo];
				       errNo: retrieveError()];
		}

		@try {
			do {
				OFString *file;

				if (wcscmp(fd.cFileName, L".") == 0 ||
				    wcscmp(fd.cFileName, L"..") == 0)
1057
1058
1059
1060
1061
1062
1063
1064

1065
1066
1067
1068
1069
1070
1071
1072
1073
1074

1075
1076
1077
1078
1079
1080
1081
1082
1083

1084
1085
1086
1087
1088
1089
1090
1091
1061
1062
1063
1064
1065
1066
1067

1068
1069
1070
1071
1072
1073
1074
1075
1076
1077

1078





1079
1080
1081

1082

1083
1084
1085
1086
1087
1088
1089







-
+









-
+
-
-
-
-
-



-
+
-







				}
			} while (FindNextFileW(handle, &fd));

			if (GetLastError() != ERROR_NO_MORE_FILES)
				@throw [OFReadFailedException
				    exceptionWithObject: self
					requestedLength: 0
						  errNo: EIO];
						  errNo: retrieveError()];
		} @finally {
			FindClose(handle);
		}
	} else {
		of_string_encoding_t encoding = [OFLocale encoding];
		WIN32_FIND_DATA fd;

		if ((handle = FindFirstFileA(
		    [path cStringWithEncoding: encoding], &fd)) ==
		    INVALID_HANDLE_VALUE) {
		    INVALID_HANDLE_VALUE)
			int errNo = 0;

			if (GetLastError() == ERROR_FILE_NOT_FOUND)
				errNo = ENOENT;

			@throw [OFOpenItemFailedException
			    exceptionWithURL: URL
					mode: nil
				       errNo: errNo];
				       errNo: retrieveError()];
		}

		@try {
			do {
				OFString *file;

				if (strcmp(fd.cFileName, ".") == 0 ||
				    strcmp(fd.cFileName, "..") == 0)
1101
1102
1103
1104
1105
1106
1107
1108

1109
1110
1111
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123




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

1138
1139
1140
1141
1142
1143
1144
1099
1100
1101
1102
1103
1104
1105

1106
1107
1108
1109
1110
1111
1112
1113
1114
1115

1116





1117
1118
1119
1120

1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

1133
1134
1135
1136
1137
1138
1139
1140







-
+









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












-
+







				}
			} while (FindNextFileA(handle, &fd));

			if (GetLastError() != ERROR_NO_MORE_FILES)
				@throw [OFReadFailedException
				    exceptionWithObject: self
					requestedLength: 0
						  errNo: EIO];
						  errNo: retrieveError()];
		} @finally {
			FindClose(handle);
		}
	}
#elif defined(OF_AMIGAOS)
	of_string_encoding_t encoding = [OFLocale encoding];
	BPTR lock;

	if ((lock = Lock([path cStringWithEncoding: encoding],
	    SHARED_LOCK)) == 0) {
	    SHARED_LOCK)) == 0)
		setErrno();

		@throw [OFOpenItemFailedException exceptionWithURL: URL
							      mode: nil
							     errNo: errno];
		@throw [OFOpenItemFailedException
		    exceptionWithURL: URL
				mode: nil
			       errNo: retrieveError()];
	}

	@try {
# ifdef OF_AMIGAOS4
		struct ExamineData *ed;
		APTR context;

		if ((context = ObtainDirContextTags(EX_FileLockInput, lock,
		    EX_DoCurrentDir, TRUE, EX_DataFields, EXF_NAME,
		    TAG_END)) == NULL)
			@throw [OFOpenItemFailedException
			    exceptionWithURL: URL
					mode: nil
				       errNo: 0];
				       errNo: retrieveError()];

		@try {
			while ((ed = ExamineDir(context)) != NULL) {
				OFString *file = [[OFString alloc]
				    initWithCString: ed->Name
					   encoding: encoding];

1154
1155
1156
1157
1158
1159
1160
1161

1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180

1181
1182
1183
1184
1185
1186
1187
1150
1151
1152
1153
1154
1155
1156

1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179
1180
1181
1182
1183







-
+


















-
+







# else
		struct FileInfoBlock fib;

		if (!Examine(lock, &fib))
			@throw [OFOpenItemFailedException
			    exceptionWithURL: URL
					mode: nil
				       errNo: 0];
				       errNo: retrieveError()];

		while (ExNext(lock, &fib)) {
			OFString *file = [[OFString alloc]
			    initWithCString: fib.fib_FileName
				   encoding: encoding];

			@try {
				[files addObject: file];
			} @finally {
				[file release];
			}
		}
# endif

		if (IoErr() != ERROR_NO_MORE_ENTRIES)
			@throw [OFReadFailedException
			    exceptionWithObject: self
				requestedLength: 0
					  errNo: EIO];
					  errNo: retrieveError()];
	} @finally {
		UnLock(lock);
	}
#else
	of_string_encoding_t encoding = [OFLocale encoding];
	DIR *dir;

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







+










-
+

-
+







	return files;
}

- (void)removeItemAtURL: (OFURL *)URL
{
	void *pool = objc_autoreleasePoolPush();
	OFString *path;
	int error;
	of_stat_t s;

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

	if (![URL.scheme isEqual: _scheme])
		@throw [OFInvalidArgumentException exception];

	path = URL.fileSystemRepresentation;

	if (of_lstat(path, &s) != 0)
	if ((error = of_lstat(path, &s)) != 0)
		@throw [OFRemoveItemFailedException exceptionWithURL: URL
							       errNo: errno];
							       errNo: error];

	if (S_ISDIR(s.st_mode)) {
		OFArray *contents;

		@try {
			contents = [self contentsOfDirectoryAtURL: URL];
		} @catch (id e) {
1334
1335
1336
1337
1338
1339
1340
1341

1342
1343
1344
1345



1346
1347
1348
1349
1350
1351
1352
1353
1331
1332
1333
1334
1335
1336
1337

1338




1339
1340
1341

1342
1343
1344
1345
1346
1347
1348







-
+
-
-
-
-
+
+
+
-







			@throw [OFRemoveItemFailedException
			    exceptionWithURL: URL
				       errNo: errno];
#endif
	}

#ifdef OF_AMIGAOS
	if (!DeleteFile([path cStringWithEncoding: [OFLocale encoding]])) {
	if (!DeleteFile([path cStringWithEncoding: [OFLocale encoding]]))
		setErrno();

		@throw [OFRemoveItemFailedException exceptionWithURL: URL
							       errNo: errno];
		@throw [OFRemoveItemFailedException
		    exceptionWithURL: URL
			       errNo: retrieveError()];
	}
#endif

	objc_autoreleasePoolPop(pool);
}

#ifdef OF_FILE_MANAGER_SUPPORTS_LINKS
- (void)linkItemAtURL: (OFURL *)source
1381
1382
1383
1384
1385
1386
1387
1388

1389
1390
1391
1392
1393
1394
1395
1376
1377
1378
1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
1390







-
+







								 object: self];

	if (!func_CreateHardLinkW(destinationPath.UTF16String,
	    sourcePath.UTF16String, NULL))
		@throw [OFLinkFailedException
		    exceptionWithSourceURL: source
			    destinationURL: destination
				     errNo: 0];
				     errNo: retrieveError()];
# endif

	objc_autoreleasePoolPop(pool);
}
#endif

#ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS
1421
1422
1423
1424
1425
1426
1427
1428

1429
1430
1431
1432
1433
1434
1435
1416
1417
1418
1419
1420
1421
1422

1423
1424
1425
1426
1427
1428
1429
1430







-
+







		@throw [OFNotImplementedException exceptionWithSelector: _cmd
								 object: self];

	if (!func_CreateSymbolicLinkW(path.UTF16String, target.UTF16String, 0))
		@throw [OFCreateSymbolicLinkFailedException
		    exceptionWithURL: URL
			      target: target
			       errNo: 0];
			       errNo: retrieveError()];
# endif

	objc_autoreleasePoolPop(pool);
}
#endif

- (bool)moveItemAtURL: (OFURL *)source
1451
1452
1453
1454
1455
1456
1457
1458

1459
1460
1461
1462
1463
1464

1465
1466
1467
1468
1469
1470
1471
1472
1446
1447
1448
1449
1450
1451
1452

1453


1454
1455
1456

1457

1458
1459
1460
1461
1462
1463
1464







-
+
-
-



-
+
-








#ifdef OF_AMIGAOS
	of_string_encoding_t encoding = [OFLocale encoding];

	if (!Rename([source.fileSystemRepresentation
	    cStringWithEncoding: encoding],
	    [destination.fileSystemRepresentation
	    cStringWithEncoding: encoding])) {
	    cStringWithEncoding: encoding]))
		setErrno();

		@throw [OFMoveItemFailedException
		    exceptionWithSourceURL: source
			    destinationURL: destination
				     errNo: errno];
				     errNo: retrieveError()];
	}
#else
	int status;

# ifdef OF_WINDOWS
	if ([OFSystemInfo isWindowsNT])
		status = _wrename(source.fileSystemRepresentation.UTF16String,
		    destination.fileSystemRepresentation.UTF16String);

Modified src/OFMutex.m from [2c5bdb0793] to [4c3fd1c33e].

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







-
+













-
-
+
+
+
+












-
+
+
+

-
+




-
-
+
+
+
+



-
+







-
+
+
+

-
+










	return [[[self alloc] init] autorelease];
}

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

	if (!of_mutex_new(&_mutex)) {
	if (of_mutex_new(&_mutex) != 0) {
		Class c = self.class;
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_initialized = true;

	return self;
}

- (void)dealloc
{
	if (_initialized) {
		if (!of_mutex_free(&_mutex)) {
			OF_ENSURE(errno == EBUSY);
		int error = of_mutex_free(&_mutex);

		if (error != 0) {
			OF_ENSURE(error == EBUSY);

			@throw [OFStillLockedException exceptionWithLock: self];
		}
	}

	[_name release];

	[super dealloc];
}

- (void)lock
{
	if (!of_mutex_lock(&_mutex))
	int error = of_mutex_lock(&_mutex);

	if (error != 0)
		@throw [OFLockFailedException exceptionWithLock: self
							  errNo: errno];
							  errNo: error];
}

- (bool)tryLock
{
	if (!of_mutex_trylock(&_mutex)) {
		if (errno == EBUSY)
	int error = of_mutex_trylock(&_mutex);

	if (error != 0) {
		if (error == EBUSY)
			return false;
		else
			@throw [OFLockFailedException exceptionWithLock: self
								  errNo: errno];
								  errNo: error];
	}

	return true;
}

- (void)unlock
{
	if (!of_mutex_unlock(&_mutex))
	int error = of_mutex_unlock(&_mutex);

	if (error != 0)
		@throw [OFUnlockFailedException exceptionWithLock: self
							    errNo: errno];
							    errNo: error];
}

- (OFString *)description
{
	if (_name == nil)
		return super.description;

	return [OFString stringWithFormat: @"<%@: %@>", self.className, _name];
}
@end

Modified src/OFObject.m from [dfafb38c1f] to [d5d0a02ee8].

307
308
309
310
311
312
313
314
315


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


314
315
316
317
318
319
320
321
322







-
-
+
+







		allocFailedException.isa = [OFAllocFailedException class];
		@throw (id)&allocFailedException;
	}

	((struct pre_ivar *)instance)->retainCount = 1;

#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	if OF_UNLIKELY (!of_spinlock_new(
	    &((struct pre_ivar *)instance)->retainCountSpinlock)) {
	if OF_UNLIKELY (of_spinlock_new(
	    &((struct pre_ivar *)instance)->retainCountSpinlock) != 0) {
		free(instance);
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
	}
#endif

	instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN);
1117
1118
1119
1120
1121
1122
1123
1124

1125
1126

1127
1128
1129
1130
1131
1132
1133
1117
1118
1119
1120
1121
1122
1123

1124
1125

1126
1127
1128
1129
1130
1131
1132
1133







-
+

-
+







	Forbid();
# endif
	PRE_IVARS->retainCount++;
# ifndef OF_AMIGAOS_M68K
	Permit();
# endif
#else
	OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
	OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock) == 0);
	PRE_IVARS->retainCount++;
	OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));
	OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock) == 0);
#endif

	return self;
}

- (unsigned int)retainCount
{
1153
1154
1155
1156
1157
1158
1159
1160

1161
1162

1163
1164
1165
1166
1167
1168
1169
1153
1154
1155
1156
1157
1158
1159

1160
1161

1162
1163
1164
1165
1166
1167
1168
1169







-
+

-
+







	Permit();

	if (retainCount == 0)
		[self dealloc];
#else
	int retainCount;

	OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
	OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock) == 0);
	retainCount = --PRE_IVARS->retainCount;
	OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));
	OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock) == 0);

	if (retainCount == 0)
		[self dealloc];
#endif
}

- (instancetype)autorelease

Modified src/OFRecursiveMutex.m from [3739c89b37] to [e5da5416e7].

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







-
+













-
-
+
+
+
+












-
+
+
+

-
+




-
-
+
+
+
+



-
+







-
+
+
+

-
+










	return [[[self alloc] init] autorelease];
}

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

	if (!of_rmutex_new(&_rmutex)) {
	if (of_rmutex_new(&_rmutex) != 0) {
		Class c = self.class;
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_initialized = true;

	return self;
}

- (void)dealloc
{
	if (_initialized) {
		if (!of_rmutex_free(&_rmutex)) {
			OF_ENSURE(errno == EBUSY);
		int error = of_rmutex_free(&_rmutex);

		if (error != 0) {
			OF_ENSURE(error == EBUSY);

			@throw [OFStillLockedException exceptionWithLock: self];
		}
	}

	[_name release];

	[super dealloc];
}

- (void)lock
{
	if (!of_rmutex_lock(&_rmutex))
	int error = of_rmutex_lock(&_rmutex);

	if (error != 0)
		@throw [OFLockFailedException exceptionWithLock: self
							  errNo: errno];
							  errNo: error];
}

- (bool)tryLock
{
	if (!of_rmutex_trylock(&_rmutex)) {
		if (errno == EBUSY)
	int error = of_rmutex_trylock(&_rmutex);

	if (error != 0) {
		if (error == EBUSY)
			return false;
		else
			@throw [OFLockFailedException exceptionWithLock: self
								  errNo: errno];
								  errNo: error];
	}

	return true;
}

- (void)unlock
{
	if (!of_rmutex_unlock(&_rmutex))
	int error = of_rmutex_unlock(&_rmutex);

	if (error != 0)
		@throw [OFUnlockFailedException exceptionWithLock: self
							    errNo: errno];
							    errNo: error];
}

- (OFString *)description
{
	if (_name == nil)
		return super.description;

	return [OFString stringWithFormat: @"<%@: %@>", self.className, _name];
}
@end

Modified src/OFSecureData.m from [7de8ab3a25] to [a977d1a98b].

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







-
+









-
+







			struct page **preallocatedPages =
			    of_tlskey_get(preallocatedPagesKey);
# endif

			numPreallocatedPages--;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
			OF_ENSURE(of_tlskey_set(numPreallocatedPagesKey,
			    (void *)numPreallocatedPages));
			    (void *)numPreallocatedPages) == 0);
# endif

			page = preallocatedPages[numPreallocatedPages];

			if (numPreallocatedPages == 0) {
				free(preallocatedPages);
				preallocatedPages = NULL;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
				OF_ENSURE(of_tlskey_set(preallocatedPagesKey,
				    preallocatedPages));
				    preallocatedPages) == 0);
# endif
			}

			return page;
		}
	}

169
170
171
172
173
174
175
176

177
178
179

180
181
182
183
184
185
186
169
170
171
172
173
174
175

176
177
178

179
180
181
182
183
184
185
186







-
+


-
+








# if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS)
	lastPage = page;

	if (firstPage == NULL)
		firstPage = page;
# else
	OF_ENSURE(of_tlskey_set(lastPageKey, page));
	OF_ENSURE(of_tlskey_set(lastPageKey, page) == 0);

	if (of_tlskey_get(firstPageKey) == NULL)
		OF_ENSURE(of_tlskey_set(firstPageKey, page));
		OF_ENSURE(of_tlskey_set(firstPageKey, page) == 0);
# endif

	return page;
}

static void
removePageIfEmpty(struct page *page)
205
206
207
208
209
210
211
212

213
214

215
216
217
218
219
220
221
205
206
207
208
209
210
211

212
213

214
215
216
217
218
219
220
221







-
+

-
+







# if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS)
	if (firstPage == page)
		firstPage = page->next;
	if (lastPage == page)
		lastPage = page->previous;
# else
	if (of_tlskey_get(firstPageKey) == page)
		OF_ENSURE(of_tlskey_set(firstPageKey, page->next));
		OF_ENSURE(of_tlskey_set(firstPageKey, page->next) == 0);
	if (of_tlskey_get(lastPageKey) == page)
		OF_ENSURE(of_tlskey_set(lastPageKey, page->previous));
		OF_ENSURE(of_tlskey_set(lastPageKey, page->previous) == 0);
# endif

	free(page);
}

static void *
allocateMemory(struct page *page, size_t bytes)
270
271
272
273
274
275
276

277
278
279



280
281
282
283
284
285
286
270
271
272
273
274
275
276
277



278
279
280
281
282
283
284
285
286
287







+
-
-
-
+
+
+







#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) && \
    !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
+ (void)initialize
{
	if (self != [OFSecureData class])
		return;

	if (of_tlskey_new(&firstPageKey) != 0 ||
	if (!of_tlskey_new(&firstPageKey) || !of_tlskey_new(&lastPageKey) ||
	    !of_tlskey_new(&preallocatedPagesKey) ||
	    !of_tlskey_new(&numPreallocatedPagesKey))
	    of_tlskey_new(&lastPageKey) != 0 ||
	    of_tlskey_new(&preallocatedPagesKey) != 0 ||
	    of_tlskey_new(&numPreallocatedPagesKey) != 0)
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}
#endif

+ (void)preallocateUnswappableMemoryWithSize: (size_t)size
{
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
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







-
+

















-
-
+
+







	size_t i;

	if (preallocatedPages != NULL)
		@throw [OFInvalidArgumentException exception];

	preallocatedPages = of_alloc_zeroed(numPages, sizeof(struct page));
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	of_tlskey_set(preallocatedPagesKey, preallocatedPages);
	OF_ENSURE(of_tlskey_set(preallocatedPagesKey, preallocatedPages) == 0);
# endif

	@try {
		for (i = 0; i < numPages; i++)
			preallocatedPages[i] = addPage(false);
	} @catch (id e) {
		for (size_t j = 0; j < i; j++)
			removePageIfEmpty(preallocatedPages[j]);

		free(preallocatedPages);
		preallocatedPages = NULL;

		@throw e;
	}

	numPreallocatedPages = numPages;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	of_tlskey_set(numPreallocatedPagesKey,
	    (void *)(uintptr_t)numPreallocatedPages);
	OF_ENSURE(of_tlskey_set(numPreallocatedPagesKey,
	    (void *)(uintptr_t)numPreallocatedPages) == 0);
# endif
#else
	@throw [OFNotImplementedException exceptionWithSelector: _cmd
							 object: self];
#endif
}

Modified src/OFString+JSONParsing.m from [57caefd874] to [87dbebe87e].

27
28
29
30
31
32
33




34
35
36
37
38
39
40
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44







+
+
+
+







#import "OFString+JSONParsing.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OFNull.h"

#import "OFInvalidJSONException.h"

#ifndef INFINITY
# define INFINITY __builtin_inf()
#endif

int _OFString_JSONParsing_reference;

static id nextObject(const char **pointer, const char *stop, size_t *line,
    size_t depthLimit);

static void

Modified src/OFString.m from [8c96d0cf6e] to [0e8c3a02df].

72
73
74
75
76
77
78




79
80
81
82
83
84
85
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89







+
+
+
+







# define strtod __strtod
#endif

#ifdef OF_AMIGAOS_M68K
/* libnix has strtod, but not strtof */
# define strtof strtod
#endif

#ifndef INFINITY
# define INFINITY __builtin_inf()
#endif

static struct {
	Class isa;
} placeholder;

#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L)
static locale_t cLocale;
2236
2237
2238
2239
2240
2241
2242
2243

2244
2245
2246
2247
2248
2249
2250







2251
2252
2253
2254
2255
2256
2257
2240
2241
2242
2243
2244
2245
2246

2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268







-
+







+
+
+
+
+
+
+







					 options: 0];
}

- (OFArray *)componentsSeparatedByString: (OFString *)delimiter
				 options: (int)options
{
	void *pool;
	OFMutableArray *array = [OFMutableArray array];
	OFMutableArray *array;
	const of_unichar_t *characters, *delimiterCharacters;
	bool skipEmpty = (options & OF_STRING_SKIP_EMPTY);
	size_t length = self.length;
	size_t delimiterLength = delimiter.length;
	size_t last;
	OFString *component;

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

	if (delimiter.length == 0)
		return [OFArray arrayWithObject: self];

	array = [OFMutableArray array];
	pool = objc_autoreleasePoolPush();

	characters = self.characters;
	delimiterCharacters = delimiter.characters;

	if (delimiterLength > length) {
		[array addObject: [[self copy] autorelease]];
2338
2339
2340
2341
2342
2343
2344
2345
2346


2347


2348
2349
2350
2351
2352















2353




2354
2355
2356
2357
2358
2359

































2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376

2377
2378
2379

2380
2381
2382


2383


2384
2385
2386






2387
2388
2389


2390




2391
2392
2393
2394
2395
2396































2397
2398
2399
2400
2401
2402
2403
2349
2350
2351
2352
2353
2354
2355


2356
2357
2358
2359
2360





2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380






2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428


2429
2430


2431
2432
2433

2434
2435
2436
2437
2438



2439
2440
2441
2442
2443
2444
2445


2446
2447
2448
2449
2450
2451
2452






2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490







-
-
+
+

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

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















-
-
+

-
-
+


-
+
+

+
+
-
-
-
+
+
+
+
+
+

-
-
+
+

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







	return [self longLongValueWithBase: 10];
}

- (long long)longLongValueWithBase: (int)base
{
	void *pool = objc_autoreleasePoolPush();
	const char *UTF8String = self.UTF8String;
	char *endPointer = NULL;
	long long value;
	bool negative = false;
	long long value = 0;

	while (of_ascii_isspace(*UTF8String))
		UTF8String++;
	errno = 0;
	value = strtoll(UTF8String, &endPointer, base);

	if ((value == LLONG_MIN || value == LLONG_MAX) && errno == ERANGE)
		@throw [OFOutOfRangeException exception];

	switch (*UTF8String) {
	case '-':
		negative = true;
	case '+':
		UTF8String++;
	}

	if (UTF8String[0] == '0') {
		if (UTF8String[1] == 'x') {
			if (base == 0)
				base = 16;

			if (base != 16 || UTF8String[2] == '\0')
				@throw [OFInvalidFormatException exception];

			UTF8String += 2;
		} else {
			if (base == 0)
				base = 8;
	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			/* Use isspace since strtoll uses the same. */
			if (!isspace((unsigned char)*endPointer))
				@throw [OFInvalidFormatException exception];

			UTF8String++;
		}
	}

	while (*UTF8String != '\0') {
		unsigned char c = of_ascii_toupper(*UTF8String++);

		if (c >= '0' && c <= '9')
			c -= '0';
		else if (c >= 'A' && c <= 'Z')
			c -= ('A' - 10);
		else if (of_ascii_isspace(c)) {
			while (*UTF8String != '\0')
				if (!of_ascii_isspace(*UTF8String++))
					@throw [OFInvalidFormatException
					    exception];

			break;
		} else
			@throw [OFInvalidFormatException exception];

		if (c >= base)
			@throw [OFInvalidFormatException exception];

		if (LLONG_MAX / base < value || LLONG_MAX - (value * base) < c)
			@throw [OFOutOfRangeException exception];

		value = (value * base) + c;
	}

	if (negative)
		value *= -1;

	objc_autoreleasePoolPop(pool);

	return value;
}

- (unsigned long long)unsignedLongLongValue
{
	return [self unsignedLongLongValueWithBase: 10];
}

- (unsigned long long)unsignedLongLongValueWithBase: (int)base
{
	void *pool = objc_autoreleasePoolPush();
	const char *UTF8String = self.UTF8String;
	char *endPointer = NULL;
	unsigned long long value;
	unsigned long long value = 0;

	/* Use isspace since strtoull uses the same. */
	while (isspace((unsigned char)*UTF8String))
	while (of_ascii_isspace(*UTF8String))
		UTF8String++;

	if (*UTF8String == '-')
	switch (*UTF8String) {
	case '-':
		@throw [OFInvalidFormatException exception];
	case '+':
		UTF8String++;

	errno = 0;
	value = strtoull(UTF8String, &endPointer, base);
	}

	if (UTF8String[0] == '0') {
		if (UTF8String[1] == 'x') {
			if (base == 0)
				base = 16;

	if (value == ULLONG_MAX && errno == ERANGE)
		@throw [OFOutOfRangeException exception];
			if (base != 16 || UTF8String[2] == '\0')
				@throw [OFInvalidFormatException exception];

			UTF8String += 2;
		} else {
			if (base == 0)
				base = 8;
	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			/* Use isspace since strtoull uses the same. */
			if (!isspace((unsigned char)*endPointer))
				@throw [OFInvalidFormatException exception];

			UTF8String++;
		}
	}

	while (*UTF8String != '\0') {
		unsigned char c = of_ascii_toupper(*UTF8String++);

		if (c >= '0' && c <= '9')
			c -= '0';
		else if (c >= 'A' && c <= 'Z')
			c -= ('A' - 10);
		else if (of_ascii_isspace(c)) {
			while (*UTF8String != '\0')
				if (!of_ascii_isspace(*UTF8String++))
					@throw [OFInvalidFormatException
					    exception];

			break;
		} else
			@throw [OFInvalidFormatException exception];

		if (c >= base)
			@throw [OFInvalidFormatException exception];

		if (ULLONG_MAX / base < value ||
		    ULLONG_MAX - (value * base) < c)
			@throw [OFOutOfRangeException exception];

		value = (value * base) + c;
	}

	objc_autoreleasePoolPop(pool);

	return value;
}

- (float)floatValue

Modified src/OFThread.m from [fe4bfba4ee] to [7d209d5958].

99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113







-
+







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

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

#ifndef OF_OBJFW_RUNTIME
	thread->_pool = objc_autoreleasePoolPush();
#endif

162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176







-
+







# endif

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

	if (!of_tlskey_new(&threadSelfKey))
	if (of_tlskey_new(&threadSelfKey) != 0)
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}

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







-
+









-
+








+ (void)of_createMainThread
{
	mainThread = [[OFThread alloc] init];
	mainThread->_thread = of_thread_current();
	mainThread->_running = OF_THREAD_RUNNING;

	if (!of_tlskey_set(threadSelfKey, mainThread))
	if (of_tlskey_set(threadSelfKey, mainThread) != 0)
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}

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

	@try {
		if (!of_thread_attr_init(&_attr))
		if (of_thread_attr_init(&_attr) != 0)
			@throw [OFInitializationFailedException
			    exceptionWithClass: self.class];
	} @catch (id e) {
		[self release];
		@throw e;
	}

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







+
+













-
-
+
+
-



-
+





+
+





-
+

-
+







	[_DNSResolver release];
	_DNSResolver = nil;
# endif
}

- (void)start
{
	int error;

	if (_running == OF_THREAD_RUNNING)
		@throw [OFThreadStillRunningException
		    exceptionWithThread: self];

	if (_running == OF_THREAD_WAITING_FOR_JOIN) {
		of_thread_detach(_thread);
		[_returnValue release];
	}

	[self retain];

	_running = OF_THREAD_RUNNING;

	if (!of_thread_new(&_thread,
	    [_name cStringWithEncoding: [OFLocale encoding]], callMain, self,
	if ((error = of_thread_new(&_thread, [_name cStringWithEncoding:
	    [OFLocale encoding]], callMain, self, &_attr)) != 0) {
	    &_attr)) {
		[self release];
		@throw [OFThreadStartFailedException
		    exceptionWithThread: self
				  errNo: errno];
				  errNo: error];
	}
}

- (id)join
{
	int error;

	if (_running == OF_THREAD_NOT_RUNNING)
		@throw [OFThreadJoinFailedException
		    exceptionWithThread: self
				  errNo: EINVAL];

	if (!of_thread_join(_thread))
	if ((error = of_thread_join(_thread)) != 0)
		@throw [OFThreadJoinFailedException exceptionWithThread: self
								  errNo: errno];
								  errNo: error];

	_running = OF_THREAD_NOT_RUNNING;

	return _returnValue;
}

- (id)copy

Modified src/OFURLHandler.m from [2d065f473d] to [b3dc531a71].

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







+
+
+
+
+
+













+







#if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS)
# import "OFHTTPURLHandler.h"
#endif

static OFMutableDictionary OF_GENERIC(OFString *, OFURLHandler *) *handlers;
#ifdef OF_HAVE_THREADS
static OFMutex *mutex;

static void
releaseMutex(void)
{
	[mutex release];
}
#endif

@implementation OFURLHandler
@synthesize scheme = _scheme;

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

	handlers = [[OFMutableDictionary alloc] init];
#ifdef OF_HAVE_THREADS
	mutex = [[OFMutex alloc] init];
	atexit(releaseMutex);
#endif

#ifdef OF_HAVE_FILES
	[self registerClass: [OFFileURLHandler class]
		  forScheme: @"file"];
#endif
#if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS)

Modified src/OFUTF8String.m from [4b2268ed9f] to [212afc270e].

1109
1110
1111
1112
1113
1114
1115
1116
1117


1118
1119
1120
1121






1122
1123


1124
1125
1126
1127
1128
1129
1130
1109
1110
1111
1112
1113
1114
1115


1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138







-
-
+
+




+
+
+
+
+
+


+
+







}

- (OFArray *)componentsSeparatedByString: (OFString *)delimiter
				 options: (int)options
{
	void *pool;
	OFMutableArray *array;
	const char *cString = delimiter.UTF8String;
	size_t cStringLength = delimiter.UTF8StringLength;
	const char *cString;
	size_t cStringLength;
	bool skipEmpty = (options & OF_STRING_SKIP_EMPTY);
	size_t last;
	OFString *component;

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

	if (delimiter.length == 0)
		return [OFArray arrayWithObject: self];

	array = [OFMutableArray array];
	pool = objc_autoreleasePoolPush();
	cString = delimiter.UTF8String;
	cStringLength = delimiter.UTF8StringLength;

	if (cStringLength > _s->cStringLength) {
		[array addObject: [[self copy] autorelease]];
		objc_autoreleasePoolPop(pool);

		return array;
	}

Modified src/condition.h from [ed39b78cbd] to [cbe5713cf5].

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





60
61
62

63
64

65
66
67

68
69
70
48
49
50
51
52
53
54





55
56
57
58
59
60
61

62
63

64
65
66

67
68
69
70







-
-
-
-
-
+
+
+
+
+


-
+

-
+


-
+



	} *waitingTasks;
} of_condition_t;
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern bool of_condition_new(of_condition_t *condition);
extern bool of_condition_signal(of_condition_t *condition);
extern bool of_condition_broadcast(of_condition_t *condition);
extern bool of_condition_wait(of_condition_t *condition, of_mutex_t *mutex);
extern bool of_condition_timed_wait(of_condition_t *condition,
extern int of_condition_new(of_condition_t *condition);
extern int of_condition_signal(of_condition_t *condition);
extern int of_condition_broadcast(of_condition_t *condition);
extern int of_condition_wait(of_condition_t *condition, of_mutex_t *mutex);
extern int of_condition_timed_wait(of_condition_t *condition,
    of_mutex_t *mutex, of_time_interval_t timeout);
#ifdef OF_AMIGAOS
extern bool of_condition_wait_or_signal(of_condition_t *condition,
extern int of_condition_wait_or_signal(of_condition_t *condition,
    of_mutex_t *mutex, ULONG *signalMask);
extern bool of_condition_timed_wait_or_signal(of_condition_t *condition,
extern int of_condition_timed_wait_or_signal(of_condition_t *condition,
    of_mutex_t *mutex, of_time_interval_t timeout, ULONG *signalMask);
#endif
extern bool of_condition_free(of_condition_t *condition);
extern int of_condition_free(of_condition_t *condition);
#ifdef __cplusplus
}
#endif

Modified src/exceptions/OFException.m from [bf7ff24437] to [9ab19e4a0d].

32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46







-
+







#import "OFString.h"
#import "OFSystemInfo.h"

#import "OFInitializationFailedException.h"
#import "OFLockFailedException.h"
#import "OFUnlockFailedException.h"

#if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS)
#ifdef OF_HAVE_THREADS
# import "mutex.h"
#endif

#if defined(OF_WINDOWS) && defined(OF_HAVE_SOCKETS)
# include <winerror.h>
#endif

71
72
73
74
75
76
77
78
79






80
81
82
83
84
85
86
71
72
73
74
75
76
77


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







-
-
+
+
+
+
+
+







#endif

#if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS)
static of_mutex_t mutex;

OF_CONSTRUCTOR()
{
	if (!of_mutex_new(&mutex))
		@throw [OFInitializationFailedException exception];
	OF_ENSURE(of_mutex_new(&mutex) == 0);
}

OF_DESTRUCTOR()
{
	of_mutex_free(&mutex);
}
#endif

OFString *
of_strerror(int errNo)
{
	OFString *ret;
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
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







-
+









-
+







	if (strerror_r(errNo, buffer, 256) != 0)
		return @"Unknown error (strerror_r failed)";

	ret = [OFString stringWithCString: buffer
				 encoding: [OFLocale encoding]];
#else
# ifdef OF_HAVE_THREADS
	if (!of_mutex_lock(&mutex))
	if (of_mutex_lock(&mutex) != 0)
		@throw [OFLockFailedException exception];

	@try {
# endif
		ret = [OFString
		    stringWithCString: strerror(errNo)
			     encoding: [OFLocale encoding]];
# ifdef OF_HAVE_THREADS
	} @finally {
		if (!of_mutex_unlock(&mutex))
		if (of_mutex_unlock(&mutex) != 0)
			@throw [OFUnlockFailedException exception];
	}
# endif
#endif

	return ret;
}

Modified src/macros.h from [365b468ef6] to [c797af37de].

146
147
148
149
150
151
152



153
154
155
156
157
158
159
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162







+
+
+








#ifdef __GNUC__
# define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
#else
# define OF_GCC_VERSION 0
#endif

#define OF_STRINGIFY(s) OF_STRINGIFY2(s)
#define OF_STRINGIFY2(s) #s

#ifndef __has_feature
# define __has_feature(x) 0
#endif

#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
353
354
355
356
357
358
359

360

361








362

363
364
365
366
367
368

369
370
371
372
373
374
375
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







+
-
+

+
+
+
+
+
+
+
+
-
+






+







#  endif
# endif
#endif

#define OF_RETAIN_COUNT_MAX UINT_MAX
#define OF_NOT_FOUND SIZE_MAX

#ifdef OBJC_COMPILING_RUNTIME
#define OF_ENSURE(cond)							\
# define OF_ENSURE(cond)						\
	do {								\
		if OF_UNLIKELY (!(cond))				\
			objc_error("ObjFWRT @ " __FILE__ ":"		\
			    OF_STRINGIFY(__LINE__),			\
			    "Failed to ensure condition:\n" #cond);	\
	} while(0)
#else
# define OF_ENSURE(cond)						\
	do {								\
		if (!(cond)) {						\
		if OF_UNLIKELY (!(cond)) {				\
			fprintf(stderr, "Failed to ensure condition "	\
			    "in " __FILE__ ":%d:\n" #cond "\n",		\
			    __LINE__);					\
			abort();					\
		}							\
	} while (0)
#endif

#define OF_UNRECOGNIZED_SELECTOR of_method_not_found(self, _cmd);
#if __has_feature(objc_arc)
# define OF_INVALID_INIT_METHOD of_method_not_found(self, _cmd);
#else
# define OF_INVALID_INIT_METHOD				\
	@try {						\

Modified src/mutex.h from [cbacd2f77f] to [5c06ee482b].

12
13
14
15
16
17
18


19
20
21
22
23
24
25
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27







+
+







 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "objfw-defs.h"

#include <errno.h>

#include "platform.h"

#if !defined(OF_HAVE_THREADS) || \
    (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
# error No mutexes available!
#endif
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77










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

95
96
97
98
99

100
101

102
103
104
105
106
107

108
109
110
111
112
113

114
115
116

117
118

119
120
121
122
123
124

125
126
127
128
129
130
131
132


133
134

135
136
137

138
139

140
141
142
143
144
145

146
147
148
149
150
151
152
153

154
155

156
157
158
159
160
161

162
163
164
165

166
167

168
169
170
171
63
64
65
66
67
68
69










70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100

101
102

103
104
105
106
107
108

109
110
111
112
113
114

115
116
117

118
119

120
121
122
123
124
125

126
127
128
129
130
131
132


133
134
135

136
137
138

139
140

141
142
143
144
145
146

147
148
149
150
151
152
153
154

155
156

157
158
159
160
161
162

163
164
165
166

167
168

169
170
171
172
173







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
















-
+




-
+

-
+





-
+





-
+


-
+

-
+





-
+






-
-
+
+

-
+


-
+

-
+





-
+







-
+

-
+





-
+



-
+

-
+




	of_tlskey_t count;
} of_rmutex_t;
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern bool of_mutex_new(of_mutex_t *mutex);
extern bool of_mutex_lock(of_mutex_t *mutex);
extern bool of_mutex_trylock(of_mutex_t *mutex);
extern bool of_mutex_unlock(of_mutex_t *mutex);
extern bool of_mutex_free(of_mutex_t *mutex);
extern bool of_rmutex_new(of_rmutex_t *rmutex);
extern bool of_rmutex_lock(of_rmutex_t *rmutex);
extern bool of_rmutex_trylock(of_rmutex_t *rmutex);
extern bool of_rmutex_unlock(of_rmutex_t *rmutex);
extern bool of_rmutex_free(of_rmutex_t *rmutex);
extern int of_mutex_new(of_mutex_t *mutex);
extern int of_mutex_lock(of_mutex_t *mutex);
extern int of_mutex_trylock(of_mutex_t *mutex);
extern int of_mutex_unlock(of_mutex_t *mutex);
extern int of_mutex_free(of_mutex_t *mutex);
extern int of_rmutex_new(of_rmutex_t *rmutex);
extern int of_rmutex_lock(of_rmutex_t *rmutex);
extern int of_rmutex_trylock(of_rmutex_t *rmutex);
extern int of_rmutex_unlock(of_rmutex_t *rmutex);
extern int of_rmutex_free(of_rmutex_t *rmutex);
#ifdef __cplusplus
}
#endif

/* Spinlocks are inlined for performance. */

static OF_INLINE void
of_thread_yield(void)
{
#if defined(OF_HAVE_SCHED_YIELD)
	sched_yield();
#elif defined(OF_WINDOWS)
	Sleep(0);
#endif
}

static OF_INLINE bool
static OF_INLINE int
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return true;
	return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return (pthread_spin_init(spinlock, 0) == 0);
	return pthread_spin_init(spinlock, 0);
#else
	return of_mutex_new(spinlock);
#endif
}

static OF_INLINE bool
static OF_INLINE int
of_spinlock_trylock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	if (of_atomic_int_cmpswap(spinlock, 0, 1)) {
		of_memory_barrier_acquire();
		return true;
		return 0;
	}

	return false;
	return EBUSY;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return (pthread_spin_trylock(spinlock) == 0);
	return pthread_spin_trylock(spinlock);
#else
	return of_mutex_trylock(spinlock);
#endif
}

static OF_INLINE bool
static OF_INLINE int
of_spinlock_lock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	size_t i;

	for (i = 0; i < OF_SPINCOUNT; i++)
		if (of_spinlock_trylock(spinlock))
			return true;
		if (of_spinlock_trylock(spinlock) == 0)
			return 0;

	while (!of_spinlock_trylock(spinlock))
	while (of_spinlock_trylock(spinlock) == EBUSY)
		of_thread_yield();

	return true;
	return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return (pthread_spin_lock(spinlock) == 0);
	return pthread_spin_lock(spinlock);
#else
	return of_mutex_lock(spinlock);
#endif
}

static OF_INLINE bool
static OF_INLINE int
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	bool ret = of_atomic_int_cmpswap(spinlock, 1, 0);

	of_memory_barrier_release();

	return ret;
	return (ret ? 0 : EINVAL);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return (pthread_spin_unlock(spinlock) == 0);
	return pthread_spin_unlock(spinlock);
#else
	return of_mutex_unlock(spinlock);
#endif
}

static OF_INLINE bool
static OF_INLINE int
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	return true;
	return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return (pthread_spin_destroy(spinlock) == 0);
	return pthread_spin_destroy(spinlock);
#else
	return of_mutex_free(spinlock);
#endif
}

Modified src/objfw-defs.h.in from [993881fae7] to [dc6785c3be].

1
2
3
4
5
6
7
8
9
10



1
2
3
4
5
6
7
-
-
-







#undef INFINITY
#undef LLONG_MAX
#undef LLONG_MIN
#undef OF_APPLE_RUNTIME
#undef OF_BIG_ENDIAN
#undef OF_FLOAT_BIG_ENDIAN
#undef OF_HAVE_ATOMIC_BUILTINS
#undef OF_HAVE_ATOMIC_OPS
#undef OF_HAVE_BUILTIN_BSWAP16
#undef OF_HAVE_BUILTIN_BSWAP32
43
44
45
46
47
48
49
50
51
52
53
40
41
42
43
44
45
46











-
-
-
-
#undef OF_HAVE___THREAD
#undef OF_NINTENDO_3DS
#undef OF_NINTENDO_DS
#undef OF_NO_SHARED
#undef OF_OBJFW_RUNTIME
#undef OF_UNIVERSAL
#undef OF_WII
#undef SIZE_MAX
#undef UINTPTR_MAX
#undef ULLONG_MAX
#undef __have_longlong64

Modified src/platform.h from [7c77ac8783] to [e661b43c0f].

125
126
127
128
129
130
131
132
133
134


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



132
133



134
135
136
137
138
139
140







-
-
-
+
+
-
-
-







#elif defined(__ANDROID__)
# define OF_ANDROID
#elif defined(__HAIKU__)
# define OF_HAIKU
#elif defined(_AIX)
# define OF_AIX
#elif defined(__MORPHOS__)
# ifndef __ixemul__
#  define OF_MORPHOS
#  define OF_AMIGAOS
# define OF_MORPHOS
# define OF_AMIGAOS
# else
#  define OF_MORPHOS_IXEMUL
# endif
#elif defined(__amigaos4__)
# define OF_AMIGAOS4
# define OF_AMIGAOS
#elif defined(__amigaos__)
# define OF_AMIGAOS_M68K
# define OF_AMIGAOS
#elif defined(__sun__)

Modified src/platform/amiga/condition.m from [022f3487c0] to [e63442b656].

23
24
25
26
27
28
29
30

31
32
33
34
35

36
37
38

39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54

55
56
57

58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75

76
77
78

79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94

95
96
97

98
99

100
101
102
103
104

105
106

107
108
109
110
111
112
113
114
115


116
117
118
119
120
121

122
123
124
125
126
127
128

129
130
131

132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
23
24
25
26
27
28
29

30
31
32
33
34

35
36
37

38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53

54
55
56

57
58
59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74

75
76
77

78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93

94
95
96

97


98

99
100
101

102
103

104
105
106
107
108
109
110
111


112
113
114
115
116
117


118

119
120
121
122
123

124
125
126

127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144







-
+




-
+


-
+





-
+









-
+


-
+





-
+











-
+


-
+







-
+







-
+


-
+
-
-
+
-



-
+

-
+







-
-
+
+




-
-
+
-





-
+


-
+









-
+








#include <proto/exec.h>
#include <devices/timer.h>
#ifndef OF_AMIGAOS4
# include <clib/alib_protos.h>
#endif

bool
int
of_condition_new(of_condition_t *condition)
{
	condition->waitingTasks = NULL;

	return true;
	return 0;
}

bool
int
of_condition_signal(of_condition_t *condition)
{
	Forbid();
	@try {
		if (condition->waitingTasks == NULL)
			return true;
			return 0;

		Signal(condition->waitingTasks->task,
		    (1ul << condition->waitingTasks->sigBit));

		condition->waitingTasks = condition->waitingTasks->next;
	} @finally {
		Permit();
	}

	return true;
	return 0;
}

bool
int
of_condition_broadcast(of_condition_t *condition)
{
	Forbid();
	@try {
		if (condition->waitingTasks == NULL)
			return true;
			return 0;

		while (condition->waitingTasks != NULL) {
			Signal(condition->waitingTasks->task,
			    (1ul << condition->waitingTasks->sigBit));

			condition->waitingTasks = condition->waitingTasks->next;
		}
	} @finally {
		Permit();
	}

	return true;
	return 0;
}

bool
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
	ULONG signalMask = 0;

	return of_condition_wait_or_signal(condition, mutex, &signalMask);
}

bool
int
of_condition_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex,
    ULONG *signalMask)
{
	struct of_condition_waiting_task waitingTask = {
		.task = FindTask(NULL),
		.sigBit = AllocSignal(-1)
	};
	bool ret;
	int error = 0;
	ULONG mask;

	if (waitingTask.sigBit == -1) {
	if (waitingTask.sigBit == -1)
		errno = EAGAIN;
		return false;
		return EAGAIN;
	}

	Forbid();

	if (!of_mutex_unlock(mutex)) {
	if ((error = of_mutex_unlock(mutex)) != 0) {
		FreeSignal(waitingTask.sigBit);
		return false;
		return error;
	}

	waitingTask.next = condition->waitingTasks;
	condition->waitingTasks = &waitingTask;

	mask = Wait((1ul << waitingTask.sigBit) | *signalMask);
	if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask))
		ret = of_mutex_lock(mutex);
	else {
		error = of_mutex_lock(mutex);
	else
		/*
		 * This should not happen - it means something interrupted the
		 * Wait(), so the best we can do is return EINTR.
		 */
		ret = false;
		errno = EINTR;
		error = EINTR;
	}

	FreeSignal(waitingTask.sigBit);

	Permit();

	return ret;
	return error;
}

bool
int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout)
{
	ULONG signalMask = 0;

	return of_condition_timed_wait_or_signal(condition, mutex, timeout,
	    &signalMask);
}

bool
int
of_condition_timed_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout, ULONG *signalMask)
{
	struct of_condition_waiting_task waitingTask = {
		.task = FindTask(NULL),
		.sigBit = AllocSignal(-1)
	};
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
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







+

-




-
+





-
+





-
+












-
-
+
+
-
-
-
+
+




-
-
+
-











-
-
-
-
-






-
+


-
+




-
+
-
-
+
-




-
+

#else
		.tr_time = {
			.tv_sec = (ULONG)timeout,
			.tv_micro = (timeout - request.tr_time.tv_sec) * 1000000
#endif
		}
	};
	int error = 0;
	ULONG mask;
	bool ret;

	NewList(&port.mp_MsgList);

	if (waitingTask.sigBit == -1 || port.mp_SigBit == -1) {
		errno = EAGAIN;
		error = EAGAIN;
		goto fail;
	}

	if (OpenDevice("timer.device", UNIT_MICROHZ,
	    (struct IORequest *)&request, 0) != 0) {
		errno = EAGAIN;
		error = EAGAIN;
		goto fail;
	}

	Forbid();

	if (!of_mutex_unlock(mutex)) {
	if ((error = of_mutex_unlock(mutex)) != 0) {
		Permit();
		goto fail;
	}

	waitingTask.next = condition->waitingTasks;
	condition->waitingTasks = &waitingTask;

	SendIO((struct IORequest *)&request);

	mask = Wait((1ul << waitingTask.sigBit) | (1ul << port.mp_SigBit) |
	    *signalMask);
	if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask))
		ret = of_mutex_lock(mutex);
	else if (mask & (1ul << port.mp_SigBit)) {
		error = of_mutex_lock(mutex);
	else if (mask & (1ul << port.mp_SigBit))
		ret = false;
		errno = ETIMEDOUT;
	} else {
		error = ETIMEDOUT;
	else
		/*
		 * This should not happen - it means something interrupted the
		 * Wait(), so the best we can do is return EINTR.
		 */
		ret = false;
		errno = EINTR;
		error = EINTR;
	}

	condition->waitingTasks = waitingTask.next;

	if (!CheckIO((struct IORequest *)&request)) {
		AbortIO((struct IORequest *)&request);
		WaitIO((struct IORequest *)&request);
	}
	CloseDevice((struct IORequest *)&request);

	Permit();

	FreeSignal(waitingTask.sigBit);
	FreeSignal(port.mp_SigBit);

	return ret;

fail:
	if (waitingTask.sigBit != -1)
		FreeSignal(waitingTask.sigBit);
	if (port.mp_SigBit != -1)
		FreeSignal(port.mp_SigBit);

	return false;
	return error;
}

bool
int
of_condition_free(of_condition_t *condition)
{
	Forbid();
	@try {
		if (condition->waitingTasks != NULL) {
		if (condition->waitingTasks != NULL)
			errno = EBUSY;
			return false;
			return EBUSY;
		}
	} @finally {
		Permit();
	}

	return true;
	return 0;
}

Modified src/platform/amiga/mutex.m from [c8d24f47bf] to [53f62a4365].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34

35
36
37
38
39

40
41
42

43
44
45

46
47
48


49
50

51
52
53

54
55
56
57
58

59
60
61

62
63
64

65
66
67

68
69
70
71
72
73

74
75
76
77
78
79

80
81
82
83
84
85

86
87
88
89
90
91

92
93
94
95
19
20
21
22
23
24
25

26
27
28
29
30

31
32
33

34
35
36
37
38

39
40
41

42
43
44

45



46
47


48
49
50

51
52
53
54
55

56
57
58

59
60
61

62
63
64

65
66
67
68
69
70

71
72
73
74
75
76

77
78
79
80
81
82

83
84
85
86
87
88

89
90
91
92
93







-
+




-
+


-
+




-
+


-
+


-
+
-
-
-
+
+
-
-
+


-
+




-
+


-
+


-
+


-
+





-
+





-
+





-
+





-
+





#include <errno.h>

#import "mutex.h"

#include <proto/exec.h>

bool
int
of_mutex_new(of_mutex_t *mutex)
{
	InitSemaphore(mutex);

	return true;
	return 0;
}

bool
int
of_mutex_lock(of_mutex_t *mutex)
{
	ObtainSemaphore(mutex);

	return true;
	return 0;
}

bool
int
of_mutex_trylock(of_mutex_t *mutex)
{
	if (!AttemptSemaphore(mutex)) {
	if (!AttemptSemaphore(mutex))
		errno = EBUSY;
		return false;
	}
		return EBUSY;


	return true;
	return 0;
}

bool
int
of_mutex_unlock(of_mutex_t *mutex)
{
	ReleaseSemaphore(mutex);

	return true;
	return 0;
}

bool
int
of_mutex_free(of_mutex_t *mutex)
{
	return true;
	return 0;
}

bool
int
of_rmutex_new(of_rmutex_t *rmutex)
{
	return of_mutex_new(rmutex);
}

bool
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
	return of_mutex_lock(rmutex);
}

bool
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	return of_mutex_trylock(rmutex);
}

bool
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	return of_mutex_unlock(rmutex);
}

bool
int
of_rmutex_free(of_rmutex_t *rmutex)
{
	return of_mutex_free(rmutex);
}

Modified src/platform/amiga/thread.m from [1416763f86] to [020e13328a].

32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55







-
+








-
+







#ifndef OF_MORPHOS
extern void of_tlskey_thread_exited(void);
#endif
static of_tlskey_t threadKey;

OF_CONSTRUCTOR()
{
	OF_ENSURE(of_tlskey_new(&threadKey));
	OF_ENSURE(of_tlskey_new(&threadKey) == 0);
}

static void
functionWrapper(void)
{
	bool detached = false;
	of_thread_t thread =
	    (of_thread_t)((struct Process *)FindTask(NULL))->pr_ExitData;
	OF_ENSURE(of_tlskey_set(threadKey, thread));
	OF_ENSURE(of_tlskey_set(threadKey, thread) == 0);

	thread->function(thread->object);

	ObtainSemaphore(&thread->semaphore);
	@try {
		thread->done = true;

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







-
+





-
+


-
+





-
+
-
-
+
-







		ReleaseSemaphore(&thread->semaphore);
	}

	if (detached)
		free(thread);
}

bool
int
of_thread_attr_init(of_thread_attr_t *attr)
{
	attr->priority = 0;
	attr->stackSize = 0;

	return true;
	return 0;
}

bool
int
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
    id object, const of_thread_attr_t *attr)
{
	OFMutableData *tags = nil;

	if ((*thread = calloc(1, sizeof(**thread))) == NULL) {
	if ((*thread = calloc(1, sizeof(**thread))) == NULL)
		errno = ENOMEM;
		return false;
		return ENOMEM;
	}

	@try {
		(*thread)->function = function;
		(*thread)->object = object;
		InitSemaphore(&(*thread)->semaphore);

		tags = [[OFMutableData alloc]
120
121
122
123
124
125
126
127

128
129

130
131
132
133
134
135
136
137
118
119
120
121
122
123
124

125


126

127
128
129
130
131
132
133







-
+
-
-
+
-







		ADD_TAG(NP_Output, ((struct Process *)FindTask(NULL))->pr_COS)
		ADD_TAG(NP_Error, ((struct Process *)FindTask(NULL))->pr_CES)
		ADD_TAG(NP_CloseInput, FALSE)
		ADD_TAG(NP_CloseOutput, FALSE)
		ADD_TAG(NP_CloseError, FALSE)

		if (attr != NULL && attr->priority != 0) {
			if (attr->priority < 1 || attr->priority > 1) {
			if (attr->priority < 1 || attr->priority > 1)
				errno = EINVAL;
				return false;
				return EINVAL;
			}

			/*
			 * -1 should be -128 (lowest possible priority) while
			 * +1 should be +127 (highest possible priority).
			 */
			ADD_TAG(NP_Priority, (attr->priority > 0
			    ? attr->priority * 127 : attr->priority * 128))
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
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







-
-
+








-
+








-
+








-
+



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












-
+


-
+











-
+







		ADD_TAG(TAG_DONE, 0)
#undef ADD_TAG

		(*thread)->task = (struct Task *)CreateNewProc(tags.items);
		if ((*thread)->task == NULL) {
			free(*thread);
			errno = EAGAIN;
			return false;
			return EAGAIN;
		}
	} @catch (id e) {
		free(*thread);
		@throw e;
	} @finally {
		[tags release];
	}

	return true;
	return 0;
}

of_thread_t
of_thread_current(void)
{
	return of_tlskey_get(threadKey);
}

bool
int
of_thread_join(of_thread_t thread)
{
	ObtainSemaphore(&thread->semaphore);

	if (thread->done) {
		ReleaseSemaphore(&thread->semaphore);

		free(thread);
		return true;
		return 0;
	}

	@try {
		if (thread->detached || thread->joinTask != NULL) {
		if (thread->detached || thread->joinTask != NULL)
			errno = EINVAL;
			return false;
		}
			return EINVAL;


		if ((thread->joinSigBit = AllocSignal(-1)) == -1) {
		if ((thread->joinSigBit = AllocSignal(-1)) == -1)
			errno = EAGAIN;
			return false;
			return EAGAIN;
		}

		thread->joinTask = FindTask(NULL);
	} @finally {
		ReleaseSemaphore(&thread->semaphore);
	}

	Wait(1ul << thread->joinSigBit);
	FreeSignal(thread->joinSigBit);

	assert(thread->done);
	free(thread);

	return true;
	return 0;
}

bool
int
of_thread_detach(of_thread_t thread)
{
	ObtainSemaphore(&thread->semaphore);

	if (thread->done)
		free(thread);
	else
		thread->detached = true;

	ReleaseSemaphore(&thread->semaphore);

	return true;
	return 0;
}

void
of_thread_set_name(const char *name)
{
}

Modified src/platform/amiga/tlskey.m from [c1bdeb2ced] to [55fe5cc12c].

48
49
50
51
52
53
54
55

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

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
48
49
50
51
52
53
54

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

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148


149
150
151
152

153
154
155
156
157
158
159
160







-
+













-
+




















-
+


-
+




















-
+




















-
+













-
-




-
+







{
	if (!semaphoreInitialized) {
		InitSemaphore(&semaphore);
		semaphoreInitialized = true;
	}
}

bool
int
of_tlskey_new(of_tlskey_t *key)
{
	if (!semaphoreInitialized) {
		/*
		 * We might be called from another constructor, while ours has
		 * not run yet. This is safe, as the constructor is definitely
		 * run before a thread is spawned.
		 */
		InitSemaphore(&semaphore);
		semaphoreInitialized = true;
	}

	if ((*key = malloc(sizeof(**key))) == NULL)
		return false;
		return ENOMEM;

	(*key)->table = NULL;

	ObtainSemaphore(&semaphore);
	@try {
		(*key)->next = NULL;
		(*key)->previous = lastKey;

		if (lastKey != NULL)
			lastKey->next = *key;

		lastKey = *key;

		if (firstKey == NULL)
			firstKey = *key;
	} @finally {
		ReleaseSemaphore(&semaphore);
	}

	/* We create the hash table lazily. */
	return true;
	return 0;
}

bool
int
of_tlskey_free(of_tlskey_t key)
{
	ObtainSemaphore(&semaphore);
	@try {
		if (key->previous != NULL)
			key->previous->next = key->next;
		if (key->next != NULL)
			key->next->previous = key->previous;

		if (firstKey == key)
			firstKey = key->next;
		if (lastKey == key)
			lastKey = key->previous;

		objc_hashtable_free(key->table);
		free(key);
	} @finally {
		ReleaseSemaphore(&semaphore);
	}

	return true;
	return 0;
}

void *
of_tlskey_get(of_tlskey_t key)
{
	void *ret;

	ObtainSemaphore(&semaphore);
	@try {
		if (key->table == NULL)
			return NULL;

		ret = objc_hashtable_get(key->table, FindTask(NULL));
	} @finally {
		ReleaseSemaphore(&semaphore);
	}

	return ret;
}

bool
int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
	ObtainSemaphore(&semaphore);
	@try {
		struct Task *task = FindTask(NULL);

		if (key->table == NULL)
			key->table = objc_hashtable_new(hashFunc, equalFunc, 2);

		if (ptr == NULL)
			objc_hashtable_delete(key->table, task);
		else
			objc_hashtable_set(key->table, task, ptr);
	} @catch (id e) {
		return false;
	} @finally {
		ReleaseSemaphore(&semaphore);
	}

	return true;
	return 0;
}

void
of_tlskey_thread_exited(void)
{
	ObtainSemaphore(&semaphore);
	@try {

Modified src/platform/morphos/tlskey.m from [b6a6f32a2b] to [ac011a1581].

15
16
17
18
19
20
21
22

23
24
25
26




27


28


29
30
31

32
15
16
17
18
19
20
21

22
23
24


25
26
27
28
29
30
31

32
33
34
35

36
37







-
+


-
-
+
+
+
+

+
+
-
+
+


-
+

 * file.
 */

#include "config.h"

#import "tlskey.h"

bool
int
of_tlskey_new(of_tlskey_t *key)
{
	return ((*key = TLSAllocA(NULL)) != TLS_INVALID_INDEX);
}
	*key = TLSAllocA(NULL);

	if (*key == TLS_INVALID_INDEX)
		return EAGAIN;

	return 0;
}
bool

int
of_tlskey_free(of_tlskey_t key)
{
	return TLSFree(key);
	return (TLSFree(key) ? 0 : EINVAL);
}

Modified src/platform/posix/condition.m from [59d3a90643] to [d7af2c3e9e].

15
16
17
18
19
20
21
22

23
24
25

26
27
28

29
30
31

32
33
34

35
36
37

38
39
40

41
42
43

44
45
46

47
48
49
50
51
52
53
54
55

56
57
58

59
60
61

62
15
16
17
18
19
20
21

22
23
24

25
26
27

28
29
30

31
32
33

34
35
36

37
38
39

40
41
42

43
44
45

46
47
48
49
50
51
52
53
54

55
56
57

58
59
60

61
62







-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+








-
+


-
+


-
+

 * file.
 */

#include "config.h"

#import "condition.h"

bool
int
of_condition_new(of_condition_t *condition)
{
	return (pthread_cond_init(condition, NULL) == 0);
	return pthread_cond_init(condition, NULL);
}

bool
int
of_condition_signal(of_condition_t *condition)
{
	return (pthread_cond_signal(condition) == 0);
	return pthread_cond_signal(condition);
}

bool
int
of_condition_broadcast(of_condition_t *condition)
{
	return (pthread_cond_broadcast(condition) == 0);
	return pthread_cond_broadcast(condition);
}

bool
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
	return (pthread_cond_wait(condition, mutex) == 0);
	return pthread_cond_wait(condition, mutex);
}

bool
int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout)
{
	struct timespec ts;

	ts.tv_sec = (time_t)timeout;
	ts.tv_nsec = (long)((timeout - ts.tv_sec) * 1000000000);

	return (pthread_cond_timedwait(condition, mutex, &ts) == 0);
	return pthread_cond_timedwait(condition, mutex, &ts);
}

bool
int
of_condition_free(of_condition_t *condition)
{
	return (pthread_cond_destroy(condition) == 0);
	return pthread_cond_destroy(condition);
}

Modified src/platform/posix/mutex.m from [608d6df3a8] to [9dc6dfa8c4].

15
16
17
18
19
20
21
22

23
24
25

26
27
28

29
30
31

32
33
34

35
36
37

38
39
40

41
42
43

44
45
46

47
48
49

50
51
52
53

54
55

56
57
58
59


60
61
62



63
64
65


66
67
68


69
70

71
72
73

74
75
76
77
78
79

80
81
82
83
84
85

86
87
88
89
90
91

92
93
94
95
96
97

98
99


100
101


102
103
104


105
106

107
108
109

110
111
112

113
114
115
116



117
118

119
120
121
122


123
124

125
126

127
128
129

130
131
132

133
134
135

136
137
138
139



140
141

142
143
144
145


146
147

148
149

150
151
152

153
154
155

156
157
158

159
160
161
162



163
164

165
166
167
168


169
170
171


172
173

174
175
176

177
178


179
180


181
182
183


184
185

186
187
15
16
17
18
19
20
21

22
23
24

25
26
27

28
29
30

31
32
33

34
35
36

37
38
39

40
41
42

43
44
45

46
47
48

49
50
51
52

53
54
55
56
57
58


59
60
61


62
63
64
65


66
67
68


69
70
71

72
73
74

75
76
77
78
79
80

81
82
83
84
85
86

87
88
89
90
91
92

93
94
95
96
97
98

99
100
101
102
103


104
105
106


107
108
109

110
111
112

113
114
115
116
117
118
119


120
121
122
123

124
125
126


127
128
129

130
131

132
133
134

135
136
137

138
139
140
141
142
143
144


145
146
147
148

149
150
151


152
153
154

155
156

157
158
159

160
161
162

163
164
165
166
167
168
169


170
171
172
173

174
175
176


177
178
179


180
181
182

183
184
185

186
187
188
189
190


191
192
193


194
195
196

197
198
199







-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+



-
+


+


-
-
+
+

-
-
+
+
+

-
-
+
+

-
-
+
+

-
+


-
+





-
+





-
+





-
+





-
+


+
+
-
-
+
+

-
-
+
+

-
+


-
+



+


-
-
+
+
+

-
+


-
-
+
+

-
+

-
+


-
+


-
+



+


-
-
+
+
+

-
+


-
-
+
+

-
+

-
+


-
+


-
+



+


-
-
+
+
+

-
+


-
-
+
+

-
-
+
+

-
+


-
+


+
+
-
-
+
+

-
-
+
+

-
+


 * file.
 */

#include "config.h"

#import "mutex.h"

bool
int
of_mutex_new(of_mutex_t *mutex)
{
	return (pthread_mutex_init(mutex, NULL) == 0);
	return pthread_mutex_init(mutex, NULL);
}

bool
int
of_mutex_lock(of_mutex_t *mutex)
{
	return (pthread_mutex_lock(mutex) == 0);
	return pthread_mutex_lock(mutex);
}

bool
int
of_mutex_trylock(of_mutex_t *mutex)
{
	return (pthread_mutex_trylock(mutex) == 0);
	return pthread_mutex_trylock(mutex);
}

bool
int
of_mutex_unlock(of_mutex_t *mutex)
{
	return (pthread_mutex_unlock(mutex) == 0);
	return pthread_mutex_unlock(mutex);
}

bool
int
of_mutex_free(of_mutex_t *mutex)
{
	return (pthread_mutex_destroy(mutex) == 0);
	return pthread_mutex_destroy(mutex);
}

#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
bool
int
of_rmutex_new(of_rmutex_t *rmutex)
{
	int error;
	pthread_mutexattr_t attr;

	if (pthread_mutexattr_init(&attr) != 0)
		return false;
	if ((error = pthread_mutexattr_init(&attr)) != 0)
		return error;

	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
		return false;
	if ((error = pthread_mutexattr_settype(&attr,
	    PTHREAD_MUTEX_RECURSIVE)) != 0)
		return error;

	if (pthread_mutex_init(rmutex, &attr) != 0)
		return false;
	if ((error = pthread_mutex_init(rmutex, &attr)) != 0)
		return error;

	if (pthread_mutexattr_destroy(&attr) != 0)
		return false;
	if ((error = pthread_mutexattr_destroy(&attr)) != 0)
		return error;

	return true;
	return 0;
}

bool
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
	return of_mutex_lock(rmutex);
}

bool
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	return of_mutex_trylock(rmutex);
}

bool
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	return of_mutex_unlock(rmutex);
}

bool
int
of_rmutex_free(of_rmutex_t *rmutex)
{
	return of_mutex_free(rmutex);
}
#else
bool
int
of_rmutex_new(of_rmutex_t *rmutex)
{
	int error;

	if (!of_mutex_new(&rmutex->mutex))
		return false;
	if ((error = of_mutex_new(&rmutex->mutex)) != 0)
		return error;

	if (!of_tlskey_new(&rmutex->count))
		return false;
	if ((error = of_tlskey_new(&rmutex->count)) != 0)
		return error;

	return true;
	return 0;
}

bool
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
	int error;

	if (count > 0) {
		if (!of_tlskey_set(rmutex->count, (void *)(count + 1)))
			return false;
		if ((error = of_tlskey_set(rmutex->count,
		    (void *)(count + 1))) != 0)
			return error;

		return true;
		return 0;
	}

	if (!of_mutex_lock(&rmutex->mutex))
		return false;
	if ((error = of_mutex_lock(&rmutex->mutex)) != 0)
		return error;

	if (!of_tlskey_set(rmutex->count, (void *)1)) {
	if ((error = of_tlskey_set(rmutex->count, (void *)1)) != 0) {
		of_mutex_unlock(&rmutex->mutex);
		return false;
		return error;
	}

	return true;
	return 0;
}

bool
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
	int error;

	if (count > 0) {
		if (!of_tlskey_set(rmutex->count, (void *)(count + 1)))
			return false;
		if ((error = of_tlskey_set(rmutex->count,
		    (void *)(count + 1))) != 0)
			return error;

		return true;
		return 0;
	}

	if (!of_mutex_trylock(&rmutex->mutex))
		return false;
	if ((error = of_mutex_trylock(&rmutex->mutex)) != 0)
		return error;

	if (!of_tlskey_set(rmutex->count, (void *)1)) {
	if ((error = of_tlskey_set(rmutex->count, (void *)1)) != 0) {
		of_mutex_unlock(&rmutex->mutex);
		return false;
		return error;
	}

	return true;
	return 0;
}

bool
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
	int error;

	if (count > 1) {
		if (!of_tlskey_set(rmutex->count, (void *)(count - 1)))
			return false;
		if ((error = of_tlskey_set(rmutex->count,
		    (void *)(count - 1))) != 0)
			return error;

		return true;
		return 0;
	}

	if (!of_tlskey_set(rmutex->count, (void *)0))
		return false;
	if ((error = of_tlskey_set(rmutex->count, (void *)0)) != 0)
		return error;

	if (!of_mutex_unlock(&rmutex->mutex))
		return false;
	if ((error = of_mutex_unlock(&rmutex->mutex)) != 0)
		return error;

	return true;
	return 0;
}

bool
int
of_rmutex_free(of_rmutex_t *rmutex)
{
	int error;

	if (!of_mutex_free(&rmutex->mutex))
		return false;
	if ((error = of_mutex_free(&rmutex->mutex)) != 0)
		return error;

	if (!of_tlskey_free(rmutex->count))
		return false;
	if ((error = of_tlskey_free(rmutex->count)) != 0)
		return error;

	return true;
	return 0;
}
#endif

Modified src/platform/posix/thread.m from [cdd7c510a1] to [08a22e6008].

83
84
85
86
87
88
89
90

91
92

93
94
95
96


97
98
99

100
101
102


103
104
105


106
107

108
109
110

111
112
113
114

115
116
117
118


119
120
121
122
123
124
125
126

127
128
129


130
131
132
133
134



135
136
137
138
139
140
141
142
143
144
145
146



147
148
149
150
151



152
153
154
155

156
157

158
159
160
161
162
163
164

165
166
167
168
169
170

171
172
173

174
175
176
177
178

179
180
181

182
183
184

185
186
187
188
189
190
191
83
84
85
86
87
88
89

90
91
92
93
94
95


96
97
98


99



100
101



102
103


104
105
106

107
108
109
110

111
112
113


114
115
116
117
118
119
120
121
122

123



124
125

126



127
128
129
130
131
132
133
134
135
136
137
138
139


140
141
142
143
144



145
146
147
148
149
150

151


152

153
154
155
156
157

158

159
160
161
162

163
164
165

166
167
168
169
170

171
172
173

174
175
176

177
178
179
180
181
182
183
184







-
+


+


-
-
+
+

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


-
+



-
+


-
-
+
+







-
+
-
-
-
+
+
-

-
-
-
+
+
+










-
-
+
+
+


-
-
-
+
+
+



-
+
-
-
+
-





-
+
-




-
+


-
+




-
+


-
+


-
+








	ctx->function(ctx->object);

	pthread_cleanup_pop(1);
	return NULL;
}

bool
int
of_thread_attr_init(of_thread_attr_t *attr)
{
	int error;
	pthread_attr_t pattr;

	if (pthread_attr_init(&pattr) != 0)
		return false;
	if ((error = pthread_attr_init(&pattr)) != 0)
		return error;

	@try {
		attr->priority = 0;
	attr->priority = 0;

		if (pthread_attr_getstacksize(&pattr, &attr->stackSize) != 0)
			return false;
	error = pthread_attr_getstacksize(&pattr, &attr->stackSize);

	} @finally {
		pthread_attr_destroy(&pattr);
	}
	pthread_attr_destroy(&pattr);


	return true;
	return error;
}

bool
int
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
    id object, const of_thread_attr_t *attr)
{
	bool ret;
	int error = 0;
	pthread_attr_t pattr;

	if (pthread_attr_init(&pattr) != 0)
		return false;
	if ((error = pthread_attr_init(&pattr)) != 0)
		return error;

	@try {
		struct thread_ctx *ctx;

		if (attr != NULL) {
			struct sched_param param;

			if (attr->priority < -1 || attr->priority > 1) {
			if (attr->priority < -1 || attr->priority > 1)
				errno = EINVAL;
				return false;
			}
				return EINVAL;


#ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED
			if (pthread_attr_setinheritsched(&pattr,
			    PTHREAD_EXPLICIT_SCHED) != 0)
				return false;
			if ((error = pthread_attr_setinheritsched(&pattr,
			    PTHREAD_EXPLICIT_SCHED)) != 0)
				return error;
#endif

			if (attr->priority < 0) {
				param.sched_priority = minPrio +
				    (1.0f + attr->priority) *
				    (normalPrio - minPrio);
			} else
				param.sched_priority = normalPrio +
				    attr->priority * (maxPrio - normalPrio);

			if (pthread_attr_setschedparam(&pattr, &param) != 0)
				return false;
			if ((error = pthread_attr_setschedparam(&pattr,
			    &param)) != 0)
				return error;

			if (attr->stackSize > 0) {
				if (pthread_attr_setstacksize(&pattr,
				    attr->stackSize) != 0)
					return false;
				if ((error = pthread_attr_setstacksize(&pattr,
				    attr->stackSize)) != 0)
					return error;
			}
		}

		if ((ctx = malloc(sizeof(*ctx))) == NULL) {
		if ((ctx = malloc(sizeof(*ctx))) == NULL)
			errno = ENOMEM;
			return false;
			return ENOMEM;
		}

		ctx->function = function;
		ctx->object = object;
		ctx->name = name;

		ret = (pthread_create(thread, &pattr,
		error = pthread_create(thread, &pattr, functionWrapper, ctx);
		    functionWrapper, ctx) == 0);
	} @finally {
		pthread_attr_destroy(&pattr);
	}

	return ret;
	return error;
}

bool
int
of_thread_join(of_thread_t thread)
{
	void *ret;

	return (pthread_join(thread, &ret) == 0);
	return pthread_join(thread, &ret);
}

bool
int
of_thread_detach(of_thread_t thread)
{
	return (pthread_detach(thread) == 0);
	return pthread_detach(thread);
}

void
of_thread_set_name(const char *name)
{
#if defined(OF_HAIKU)
	rename_thread(find_thread(NULL), name);

Modified src/platform/posix/tlskey.m from [01a5f7adde] to [b21f6b68b0].

15
16
17
18
19
20
21
22

23
24
25

26
27
28

29
30
31

32
15
16
17
18
19
20
21

22
23
24

25
26
27

28
29
30

31
32







-
+


-
+


-
+


-
+

 * file.
 */

#include "config.h"

#import "tlskey.h"

bool
int
of_tlskey_new(of_tlskey_t *key)
{
	return (pthread_key_create(key, NULL) == 0);
	return pthread_key_create(key, NULL);
}

bool
int
of_tlskey_free(of_tlskey_t key)
{
	return (pthread_key_delete(key) == 0);
	return pthread_key_delete(key);
}

Modified src/platform/windows/condition.m from [848a636ef0] to [bcc658da38].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34


35
36

37
38
39

40
41
42
43
44
45
46

47
48
49
50
51
52

53
54
55

56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72

73
74
75

76
77

78
79
80
81


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

95
96
97
98
99
100
101
102
103

104
105
106

107
108
109
110


111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126

127
128
129
130
131
132
133
134
135

136
137
138

139
140
141


142
143

144
19
20
21
22
23
24
25

26
27
28
29
30

31



32
33


34
35
36

37
38
39
40
41
42


43
44
45
46
47
48

49
50
51

52
53
54
55
56
57
58
59
60


61
62
63
64
65
66
67

68
69
70

71
72
73
74
75
76


77
78
79
80
81
82
83
84
85
86
87
88
89


90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105


106
107
108
109
110
111
112
113
114
115
116


117
118
119
120


121
122
123
124
125
126
127
128
129

130
131
132

133



134
135


136
137







-
+




-
+
-
-
-
+
+
-
-
+


-
+





-
-
+





-
+


-
+








-
-
+






-
+


-
+


+


-
-
+
+











-
-
+








-
+



+


-
-
+
+









-
-
+



-
-
+








-
+


-
+
-
-
-
+
+
-
-
+


#include <errno.h>

#import "condition.h"

#include <windows.h>

bool
int
of_condition_new(of_condition_t *condition)
{
	condition->count = 0;

	if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL) {
	if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL)
		errno = EAGAIN;
		return false;
	}
		return EAGAIN;


	return true;
	return 0;
}

bool
int
of_condition_signal(of_condition_t *condition)
{
	if (!SetEvent(condition->event)) {
		switch (GetLastError()) {
		case ERROR_INVALID_HANDLE:
			errno = EINVAL;
			return false;
			return EINVAL;
		default:
			OF_ENSURE(0);
		}
	}

	return true;
	return 0;
}

bool
int
of_condition_broadcast(of_condition_t *condition)
{
	int count = condition->count;

	for (int i = 0; i < count; i++) {
		if (!SetEvent(condition->event)) {
			switch (GetLastError()) {
			case ERROR_INVALID_HANDLE:
				errno = EINVAL;
				return false;
				return EINVAL;
			default:
				OF_ENSURE(0);
			}
		}
	}

	return true;
	return 0;
}

bool
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
	int error;
	DWORD status;

	if (!of_mutex_unlock(mutex))
		return false;
	if ((error = of_mutex_unlock(mutex)) != 0)
		return error;

	of_atomic_int_inc(&condition->count);
	status = WaitForSingleObject(condition->event, INFINITE);
	of_atomic_int_dec(&condition->count);

	switch (status) {
	case WAIT_OBJECT_0:
		return of_mutex_lock(mutex);
	case WAIT_FAILED:
		switch (GetLastError()) {
		case ERROR_INVALID_HANDLE:
			errno = EINVAL;
			return false;
			return EINVAL;
		default:
			OF_ENSURE(0);
		}
	default:
		OF_ENSURE(0);
	}
}

bool
int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout)
{
	int error;
	DWORD status;

	if (!of_mutex_unlock(mutex))
		return false;
	if ((error = of_mutex_unlock(mutex)) != 0)
		return error;

	of_atomic_int_inc(&condition->count);
	status = WaitForSingleObject(condition->event, timeout * 1000);
	of_atomic_int_dec(&condition->count);

	switch (status) {
	case WAIT_OBJECT_0:
		return of_mutex_lock(mutex);
	case WAIT_TIMEOUT:
		errno = ETIMEDOUT;
		return false;
		return ETIMEDOUT;
	case WAIT_FAILED:
		switch (GetLastError()) {
		case ERROR_INVALID_HANDLE:
			errno = EINVAL;
			return false;
			return EINVAL;
		default:
			OF_ENSURE(0);
		}
	default:
		OF_ENSURE(0);
	}
}

bool
int
of_condition_free(of_condition_t *condition)
{
	if (condition->count != 0) {
	if (condition->count != 0)
		errno = EBUSY;
		return false;
	}
		return EBUSY;


	return CloseHandle(condition->event);
	return (CloseHandle(condition->event) ? 0 : EINVAL);
}

Modified src/platform/windows/mutex.m from [c67aeb237e] to [872d7f229b].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34

35
36
37
38
39

40
41
42

43
44
45

46
47
48


49
50

51
52
53

54
55
56
57
58

59
60
61

62
63
64
65
66

67
68
69

70
71
72
73
74
75

76
77
78
79
80
81

82
83
84
85
86
87

88
89
90
91
92
93

94
95
96
97
19
20
21
22
23
24
25

26
27
28
29
30

31
32
33

34
35
36
37
38

39
40
41

42
43
44

45



46
47


48
49
50

51
52
53
54
55

56
57
58

59
60
61
62
63

64
65
66

67
68
69
70
71
72

73
74
75
76
77
78

79
80
81
82
83
84

85
86
87
88
89
90

91
92
93
94
95







-
+




-
+


-
+




-
+


-
+


-
+
-
-
-
+
+
-
-
+


-
+




-
+


-
+




-
+


-
+





-
+





-
+





-
+





-
+





#include <errno.h>

#import "mutex.h"

#include <windows.h>

bool
int
of_mutex_new(of_mutex_t *mutex)
{
	InitializeCriticalSection(mutex);

	return true;
	return 0;
}

bool
int
of_mutex_lock(of_mutex_t *mutex)
{
	EnterCriticalSection(mutex);

	return true;
	return 0;
}

bool
int
of_mutex_trylock(of_mutex_t *mutex)
{
	if (!TryEnterCriticalSection(mutex)) {
	if (!TryEnterCriticalSection(mutex))
		errno = EBUSY;
		return false;
	}
		return EBUSY;


	return true;
	return 0;
}

bool
int
of_mutex_unlock(of_mutex_t *mutex)
{
	LeaveCriticalSection(mutex);

	return true;
	return 0;
}

bool
int
of_mutex_free(of_mutex_t *mutex)
{
	DeleteCriticalSection(mutex);

	return true;
	return 0;
}

bool
int
of_rmutex_new(of_rmutex_t *rmutex)
{
	return of_mutex_new(rmutex);
}

bool
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
	return of_mutex_lock(rmutex);
}

bool
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	return of_mutex_trylock(rmutex);
}

bool
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	return of_mutex_unlock(rmutex);
}

bool
int
of_rmutex_free(of_rmutex_t *rmutex)
{
	return of_mutex_free(rmutex);
}

Modified src/platform/windows/thread.m from [d3d9eb9ec8] to [ea501b1747].

33
34
35
36
37
38
39
40

41
42
43
44
45
46

47
48
49

50
51
52
53
54
55
56
57
58

59
60

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

74
75

76
77
78
79
80
81
82
83
84
85

86
87
88
89

90
91
92

93
94
95
96
97
98
99
100

101
102
103
104
105
106

107
108
109

110
111
112
113
114
115

116
117
118
119
120

121
122
123
124
125
126
127
128
129

130
131
132
133
134

135
136
137
138
139
140
33
34
35
36
37
38
39

40
41
42
43
44
45

46
47
48

49
50
51
52
53
54
55
56
57

58


59

60
61
62
63
64
65
66
67
68
69
70

71


72

73
74
75
76
77
78
79
80

81
82
83
84

85
86
87

88
89
90
91
92
93
94


95
96
97
98
99
100

101
102
103

104
105
106
107
108
109

110
111
112
113


114
115
116
117
118
119
120
121
122

123
124
125
126
127

128
129
130
131
132
133
134







-
+





-
+


-
+








-
+
-
-
+
-











-
+
-
-
+
-








-
+



-
+


-
+






-
-
+





-
+


-
+





-
+



-
-
+








-
+




-
+






functionWrapper(struct thread_context *context)
{
	context->function(context->object);

	free(context);
}

bool
int
of_thread_attr_init(of_thread_attr_t *attr)
{
	attr->priority = 0;
	attr->stackSize = 0;

	return true;
	return 0;
}

bool
int
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
    id object, const of_thread_attr_t *attr)
{
	DWORD priority = THREAD_PRIORITY_NORMAL;
	struct thread_context *context;
	DWORD threadID;

	if (attr != NULL && attr->priority != 0) {
		if (attr->priority < -1 || attr->priority > 1) {
		if (attr->priority < -1 || attr->priority > 1)
			errno = EINVAL;
			return false;
			return EINVAL;
		}

		if (attr->priority < 0)
			priority = THREAD_PRIORITY_LOWEST +
			    (1.0 + attr->priority) *
			    (THREAD_PRIORITY_NORMAL - THREAD_PRIORITY_LOWEST);
		else
			priority = THREAD_PRIORITY_NORMAL +
			    attr->priority *
			    (THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_NORMAL);
	}

	if ((context = malloc(sizeof(*context))) == NULL) {
	if ((context = malloc(sizeof(*context))) == NULL)
		errno = ENOMEM;
		return false;
		return ENOMEM;
	}

	context->function = function;
	context->object = object;

	*thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0),
	    (LPTHREAD_START_ROUTINE)functionWrapper, context, 0, &threadID);

	if (thread == NULL) {
		int errNo;
		int error;

		switch (GetLastError()) {
		case ERROR_NOT_ENOUGH_MEMORY:
			errNo = ENOMEM;
			error = ENOMEM;
			break;
		case ERROR_ACCESS_DENIED:
			errNo = EACCES;
			error = EACCES;
			break;
		default:
			OF_ENSURE(0);
		}

		free(context);
		errno = errNo;
		return false;
		return error;
	}

	if (attr != NULL && attr->priority != 0)
		OF_ENSURE(!SetThreadPriority(*thread, priority));

	return true;
	return 0;
}

bool
int
of_thread_join(of_thread_t thread)
{
	switch (WaitForSingleObject(thread, INFINITE)) {
	case WAIT_OBJECT_0:
		CloseHandle(thread);
		return true;
		return 0;
	case WAIT_FAILED:
		switch (GetLastError()) {
		case ERROR_INVALID_HANDLE:
			errno = EINVAL;
			return false;
			return EINVAL;
		default:
			OF_ENSURE(0);
		}
	default:
		OF_ENSURE(0);
	}
}

bool
int
of_thread_detach(of_thread_t thread)
{
	CloseHandle(thread);

	return true;
	return 0;
}

void
of_thread_set_name(const char *name)
{
}

Modified src/platform/windows/tlskey.m from [c8aecc8bc3] to [a76af40888].

15
16
17
18
19
20
21
22

23
24
25
26




27


28


29
30
31

32
15
16
17
18
19
20
21

22
23
24


25
26
27
28
29
30
31

32
33
34
35

36
37







-
+


-
-
+
+
+
+

+
+
-
+
+


-
+

 * file.
 */

#include "config.h"

#import "tlskey.h"

bool
int
of_tlskey_new(of_tlskey_t *key)
{
	return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES);
}
	*key = TlsAlloc();

	if (*key == TLS_OUT_OF_INDEXES)
		return EAGAIN;

	return 0;
}
bool

int
of_tlskey_free(of_tlskey_t key)
{
	return TlsFree(key);
	return (TlsFree(key) ? 0 : EINVAL);
}

Modified src/runtime/Makefile from [db9b1528cf] to [f0432ebc20].

54
55
56
57
58
59
60

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







+






${SFDC_INLINE_H}: ${SFD_FILE}
	sfdc -q --target=${SFDC_TARGET} --mode=macros -o $@ $<; \

${CVINCLUDE_INLINE_H}: morphos.fd morphos-clib.h
	cvinclude.pl --quiet --fd=morphos.fd --clib=morphos-clib.h --inlines=$@

CPPFLAGS += -I. -I.. -I../..					\
	    -DOBJC_COMPILING_RUNTIME				\
	    -DOBJFWRT_AMIGA_LIB=\"${OBJFWRT_AMIGA_LIB}\"	\
	    -DOBJFWRT_LIB_MAJOR=${OBJFWRT_LIB_MAJOR}		\
	    -DOBJFWRT_LIB_MINOR=${OBJFWRT_LIB_MINOR}
AMIGA_LIB_CFLAGS += -DOBJC_COMPILING_AMIGA_LIBRARY
LD = ${OBJC}
FRAMEWORK_LIBS = ${LIBS}

Modified src/runtime/amiga-glue.m from [15f440e90e] to [7a9a2d20bd].

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







-
+













-
+
-



-
-

-
+







# define PPC_PARAMS(...) (void)
# define M68K_ARG OBJC_M68K_ARG
#else
# define PPC_PARAMS(...) (__VA_ARGS__)
# define M68K_ARG(...)
#endif

extern bool objc_init(unsigned int, struct objc_libc *, FILE *, FILE *);
extern bool objc_init(unsigned int, struct objc_libc *);

#ifdef OF_MORPHOS
/* All __saveds functions in this file need to use the SysV ABI */
__asm__ (
    ".section .text\n"
    ".align 2\n"
    "__restore_r13:\n"
    "	lwz	%r13, 44(%r12)\n"
    "	blr\n"
);
#endif

bool __saveds
glue_objc_init PPC_PARAMS(unsigned int version, struct objc_libc *libc,
glue_objc_init PPC_PARAMS(unsigned int version, struct objc_libc *libc)
    FILE *stdout_, FILE *stderr_)
{
	M68K_ARG(unsigned int, version, d0)
	M68K_ARG(struct objc_libc *, libc, a0)
	M68K_ARG(FILE *, stdout_, a1)
	M68K_ARG(FILE *, stderr_, a2)

	return objc_init(version, libc, stdout_, stderr_);
	return objc_init(version, libc);
}

void __saveds
glue___objc_exec_class PPC_PARAMS(struct objc_module *module)
{
	M68K_ARG(struct objc_module *, module, a0)

Modified src/runtime/amiga-library.m from [aa8e67d72d] to [359a58f2d8].

43
44
45
46
47
48
49







50
51
52
53
54
55
56
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63







+
+
+
+
+
+
+








/* This always needs to be the first thing in the file. */
int
_start()
{
	return -1;
}

#ifdef OF_AMIGAOS_M68K
void
__init_eh(void)
{
}
#endif

struct ObjFWRTBase {
	struct Library library;
	void *segList;
	struct ObjFWRTBase *parent;
	char *dataSeg;
	bool initialized;
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
161
162
163
164
165
166
167


168
169
170
171
172
173
174







-
-







extern id glue_objc_createTaggedPointer(void);

#ifdef OF_MORPHOS
const ULONG __abox__ = 1;
#endif
struct ExecBase *SysBase;
struct objc_libc libc;
FILE *stdout;
FILE *stderr;

#if defined(OF_AMIGAOS_M68K)
__asm__ (
    ".text\n"
    ".globl ___restore_a4\n"
    ".align 1\n"
    "___restore_a4:\n"
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
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







-
+
-
















-
-







static void *
lib_null(void)
{
	return NULL;
}

bool
objc_init(unsigned int version, struct objc_libc *libc_, FILE *stdout_,
objc_init(unsigned int version, struct objc_libc *libc_)
    FILE *stderr_)
{
#ifdef OF_AMIGAOS_M68K
	OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6)
#else
	register struct ObjFWRTBase *r12 __asm__("r12");
	struct ObjFWRTBase *base = r12;
#endif
#ifdef OF_MORPHOS
	void *frame;
#endif
	uintptr_t *iter, *iter0;

	if (version > 1)
		return false;

	memcpy(&libc, libc_, sizeof(libc));
	stdout = stdout_;
	stderr = stderr_;

#ifdef OF_AMIGAOS_M68K
	if ((size_t)_EH_FRAME_BEGINS__ != (size_t)_EH_FRAME_OBJECTS__)
		return false;

	for (size_t i = 1; i <= (size_t)_EH_FRAME_BEGINS__; i++)
		libc.__register_frame_info((&_EH_FRAME_BEGINS__)[i],
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
485
486
487
488
489
490
491



























492
493
494
495
496
497
498







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








void
free(void *ptr)
{
	libc.free(ptr);
}

int
fprintf(FILE *restrict stream, const char *restrict fmt, ...)
{
	int ret;
	va_list args;

	va_start(args, fmt);
	ret = libc.vfprintf(stream, fmt, args);
	va_end(args);

	return ret;
}

int
fflush(FILE *restrict stream)
{
	return libc.fflush(stream);
}

void
abort(void)
{
	libc.abort();

	OF_UNREACHABLE
}

#ifdef HAVE_SJLJ_EXCEPTIONS
int
_Unwind_SjLj_RaiseException(void *ex)
{
	return libc._Unwind_SjLj_RaiseException(ex);
}
#else
592
593
594
595
596
597
598

599
600
601
602

































603
604
605
606
607
608
609
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
610
611
612
613
614







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







void
_Unwind_Resume(void *ex)
{
	libc._Unwind_Resume(ex);
}
#endif

#ifdef OF_AMIGAOS_M68K
int *
objc_get_errno(void)
{
	return libc.get_errno();
int
snprintf(char *restrict str, size_t size, const char *restrict fmt, ...)
{
	va_list args;
	int ret;

	va_start(args, fmt);
	ret = vsnprintf(str, size, fmt, args);
	va_end(args);

	return ret;
}

int
vsnprintf(char *restrict str, size_t size, const char *restrict fmt,
    va_list args)
{
	return libc.vsnprintf(str, size, fmt, args);
}
#endif

int
atexit(void (*function)(void))
{
	return libc.atexit(function);
}

void
exit(int status)
{
	libc.exit(status);

	OF_UNREACHABLE
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
static CONST_APTR functionTable[] = {
#ifdef OF_MORPHOS
	(CONST_APTR)FUNCARRAY_BEGIN,

Modified src/runtime/amigaos3.sfd from [52fd389150] to [27d28cf09f].

1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







==base _ObjFWRTBase
==basetype struct Library *
==libname objfwrt68k.library
==bias 30
==public
* The following function is only for the linklib.
bool glue_objc_init(unsigned int version, struct objc_libc *libc, FILE *stdout, FILE *stderr)(d0,a0,a1,a2)
bool glue_objc_init(unsigned int version, struct objc_libc *libc)(d0,a0)
void glue___objc_exec_class(struct objc_module *_Nonnull module)(a0)
IMP _Nonnull glue_objc_msg_lookup(id _Nullable object, SEL _Nonnull selector)(a0,a1)
IMP _Nonnull glue_objc_msg_lookup_stret(id _Nullable object, SEL _Nonnull selector)(a0,a1)
IMP _Nonnull glue_objc_msg_lookup_super(struct objc_super *_Nonnull super, SEL _Nonnull selector)(a0,a1)
IMP _Nonnull glue_objc_msg_lookup_super_stret(struct objc_super *_Nonnull super, SEL _Nonnull selector)(a0,a1)
Class _Nullable glue_objc_lookUpClass(const char *_Nonnull name)(a0)
Class _Nullable glue_objc_getClass(const char *_Nonnull name)(a0)

Modified src/runtime/arc.m from [7f174d7d34] to [0378415cdf].

47
48
49
50
51
52
53
54
55


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


54
55
56
57
58
59
60
61
62







-
-
+
+







}

OF_CONSTRUCTOR()
{
	hashtable = objc_hashtable_new(hash, equal, 2);

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_new(&spinlock))
		OBJC_ERROR("Failed to create spinlock!")
	if (of_spinlock_new(&spinlock) != 0)
		OBJC_ERROR("Failed to create spinlock!");
#endif
}

id
objc_retain(id object)
{
	return [object retain];
118
119
120
121
122
123
124
125
126


127
128
129
130
131
132
133
118
119
120
121
122
123
124


125
126
127
128
129
130
131
132
133







-
-
+
+








id
objc_storeWeak(id *object, id value)
{
	struct weak_ref *old;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_lock(&spinlock))
		OBJC_ERROR("Failed to lock spinlock!")
	if (of_spinlock_lock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if (*object != nil &&
	    (old = objc_hashtable_get(hashtable, *object)) != NULL) {
		for (size_t i = 0; i < old->count; i++) {
			if (old->locations[i] == object) {
				if (--old->count == 0) {
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
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







-
+








-
-
+
+












-
-
+
+







-
-
+
+








			objc_hashtable_set(hashtable, value, ref);
		}

		if ((ref->locations = realloc(ref->locations,
		    (ref->count + 1) * sizeof(id *))) == NULL)
			OBJC_ERROR("Not enough memory to allocate weak "
			    "reference!")
			    "reference!");

		ref->locations[ref->count++] = object;
	} else
		value = nil;

	*object = value;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_unlock(&spinlock))
		OBJC_ERROR("Failed to unlock spinlock!")
	if (of_spinlock_unlock(&spinlock) != 0)
		OBJC_ERROR("Failed to unlock spinlock!");
#endif

	return value;
}

id
objc_loadWeakRetained(id *object)
{
	id value = nil;
	struct weak_ref *ref;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_lock(&spinlock))
		OBJC_ERROR("Failed to lock spinlock!")
	if (of_spinlock_lock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if (*object != nil &&
	    (ref = objc_hashtable_get(hashtable, *object)) != NULL)
		value = *object;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_unlock(&spinlock))
		OBJC_ERROR("Failed to unlock spinlock!")
	if (of_spinlock_unlock(&spinlock) != 0)
		OBJC_ERROR("Failed to unlock spinlock!");
#endif

	if (class_respondsToSelector(object_getClass(value),
	    @selector(retainWeakReference)) && [value retainWeakReference])
		return value;

	return nil;
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
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







-
-
+
+
















-
-
+
+









-
-
+
+












-
-
+
+



void
objc_moveWeak(id *dest, id *src)
{
	struct weak_ref *ref;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_lock(&spinlock))
		OBJC_ERROR("Failed to lock spinlock!")
	if (of_spinlock_lock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if (*src != nil &&
	    (ref = objc_hashtable_get(hashtable, *src)) != NULL) {
		for (size_t i = 0; i < ref->count; i++) {
			if (ref->locations[i] == src) {
				ref->locations[i] = dest;
				break;
			}
		}
	}

	*dest = *src;
	*src = nil;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_unlock(&spinlock))
		OBJC_ERROR("Failed to unlock spinlock!")
	if (of_spinlock_unlock(&spinlock) != 0)
		OBJC_ERROR("Failed to unlock spinlock!");
#endif
}

void
objc_zero_weak_references(id value)
{
	struct weak_ref *ref;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_lock(&spinlock))
		OBJC_ERROR("Failed to lock spinlock!")
	if (of_spinlock_lock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if ((ref = objc_hashtable_get(hashtable, value)) != NULL) {
		for (size_t i = 0; i < ref->count; i++)
			*ref->locations[i] = nil;

		objc_hashtable_delete(hashtable, value);
		free(ref->locations);
		free(ref);
	}

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_unlock(&spinlock))
		OBJC_ERROR("Failed to unlock spinlock!")
	if (of_spinlock_unlock(&spinlock) != 0)
		OBJC_ERROR("Failed to unlock spinlock!");
#endif
}

Modified src/runtime/autorelease.m from [e5ceb906d0] to [0e5c7aa48b].

49
50
51
52
53
54
55
56
57
58



59
60
61
62
63
64
65
49
50
51
52
53
54
55



56
57
58
59
60
61
62
63
64
65







-
-
-
+
+
+







static uintptr_t count = 0;
static uintptr_t size = 0;
#endif

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_CONSTRUCTOR()
{
	OF_ENSURE(of_tlskey_new(&objectsKey));
	OF_ENSURE(of_tlskey_new(&countKey));
	OF_ENSURE(of_tlskey_new(&sizeKey));
	OF_ENSURE(of_tlskey_new(&objectsKey) == 0);
	OF_ENSURE(of_tlskey_new(&countKey) == 0);
	OF_ENSURE(of_tlskey_new(&sizeKey) == 0);
}
#endif

void *
objc_autoreleasePoolPush()
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
96
97
98
99
100
101
102
103
104


105
106
107
108
109

110
111
112
113
114
115
116
96
97
98
99
100
101
102


103
104
105
106
107
108

109
110
111
112
113
114
115
116







-
-
+
+




-
+








	if (freeMem) {
		free(objects);
		objects = NULL;
#if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS)
		size = 0;
#else
		OF_ENSURE(of_tlskey_set(objectsKey, objects));
		OF_ENSURE(of_tlskey_set(sizeKey, (void *)0));
		OF_ENSURE(of_tlskey_set(objectsKey, objects) == 0);
		OF_ENSURE(of_tlskey_set(sizeKey, (void *)0) == 0);
#endif
	}

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	OF_ENSURE(of_tlskey_set(countKey, (void *)count));
	OF_ENSURE(of_tlskey_set(countKey, (void *)count) == 0);
#endif
}

id
_objc_rootAutorelease(id object)
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
125
126
127
128
129
130
131
132
133


134
135
136
137
138
139
140

141
142
143
144
125
126
127
128
129
130
131


132
133
134
135
136
137
138
139

140
141
142
143
144







-
-
+
+






-
+




		else
			size *= 2;

		OF_ENSURE((objects =
		    realloc(objects, size * sizeof(id))) != NULL);

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
		OF_ENSURE(of_tlskey_set(objectsKey, objects));
		OF_ENSURE(of_tlskey_set(sizeKey, (void *)size));
		OF_ENSURE(of_tlskey_set(objectsKey, objects) == 0);
		OF_ENSURE(of_tlskey_set(sizeKey, (void *)size) == 0);
#endif
	}

	objects[count++] = object;

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	OF_ENSURE(of_tlskey_set(countKey, (void *)count));
	OF_ENSURE(of_tlskey_set(countKey, (void *)count) == 0);
#endif

	return object;
}

Modified src/runtime/class.m from [0dc727f4b5] to [c47f6af2b8].

339
340
341
342
343
344
345







346
347
348
349
350
351
352
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359







+
+
+
+
+
+
+








	if (class->info & OBJC_CLASS_INFO_INITIALIZED)
		return;

	if (class->superclass)
		initializeClass(class->superclass);

	/*
	 * Avoid double-initialization: One of the superclasses' +[initialize]
	 * might have called this class and hence it already got initialized.
	 */
	if (class->info & OBJC_CLASS_INFO_INITIALIZED)
		return;

	class->info |= OBJC_CLASS_INFO_DTABLE;
	class->isa->info |= OBJC_CLASS_INFO_DTABLE;

	objc_update_dtable(class);
	objc_update_dtable(class->isa);

	/*
466
467
468
469
470
471
472
473

474
475
476
477
478

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

480
481
482
483
484

485
486
487
488
489
490
491
492







-
+




-
+







Class
objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
{
	struct objc_class *class, *metaclass;
	Class iter, rootclass = Nil;

	if (extraBytes > LONG_MAX)
		OBJC_ERROR("extraBytes out of range!")
		OBJC_ERROR("extraBytes out of range!");

	if ((class = calloc(1, sizeof(*class))) == NULL ||
	    (metaclass = calloc(1, sizeof(*class))) == NULL)
		OBJC_ERROR("Not enough memory to allocate class pair for class "
		    "%s!", name)
		    "%s!", name);

	class->isa = metaclass;
	class->superclass = superclass;
	class->name = name;
	class->info = OBJC_CLASS_INFO_CLASS;
	class->instanceSize = (superclass != Nil ?
	    superclass->instanceSize : 0) + (long)extraBytes;

Modified src/runtime/exception.m from [ff0a7a161b] to [50eac6751c].

244
245
246
247
248
249
250
251
252


253
254
255
256
257
258
259
244
245
246
247
248
249
250


251
252
253
254
255
256
257
258
259







-
-
+
+







static objc_uncaught_exception_handler_t uncaughtExceptionHandler;
static struct objc_exception emergencyExceptions[NUM_EMERGENCY_EXCEPTIONS];
#ifdef OF_HAVE_THREADS
static of_spinlock_t emergencyExceptionsSpinlock;

OF_CONSTRUCTOR()
{
	if (!of_spinlock_new(&emergencyExceptionsSpinlock))
		OBJC_ERROR("Cannot create spinlock!")
	if (of_spinlock_new(&emergencyExceptionsSpinlock) != 0)
		OBJC_ERROR("Cannot create spinlock!");
}
#endif

static uint64_t
readULEB128(const uint8_t **ptr)
{
	uint64_t value = 0;
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
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







-
+



















-
+








-
+







#endif
#ifdef HAVE__UNWIND_GETTEXTRELBASE
	case DW_EH_PE_textrel:
		return _Unwind_GetTextRelBase(ctx);
#endif
	}

	OBJC_ERROR("Unknown encoding!")
	OBJC_ERROR("Unknown encoding!");
}

static size_t
sizeForEncoding(uint8_t enc)
{
	if (enc == DW_EH_PE_omit)
		return 0;

	switch (enc & 0x07) {
	case DW_EH_PE_absptr:
		return sizeof(void *);
	case DW_EH_PE_udata2:
		return 2;
	case DW_EH_PE_udata4:
		return 4;
	case DW_EH_PE_udata8:
		return 8;
	}

	OBJC_ERROR("Unknown encoding!")
	OBJC_ERROR("Unknown encoding!");
}

static uint64_t
readValue(uint8_t enc, const uint8_t **ptr)
{
	uint64_t value;

	if (enc == DW_EH_PE_aligned)
		OBJC_ERROR("DW_EH_PE_aligned is not implemented!")
		OBJC_ERROR("DW_EH_PE_aligned is not implemented!");

#define READ(type)					\
	{						\
		type tmp;				\
		memcpy(&tmp, *ptr, sizeof(type));	\
		value = tmp;				\
		*ptr += sizeForEncoding(enc);		\
367
368
369
370
371
372
373
374

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

374
375
376
377
378
379
380
381







-
+







	case DW_EH_PE_sdata2:
		READ(int16_t)
	case DW_EH_PE_sdata4:
		READ(int32_t)
	case DW_EH_PE_sdata8:
		READ(int64_t)
	default:
		OBJC_ERROR("Unknown encoding!")
		OBJC_ERROR("Unknown encoding!");
	}
#undef READ

	return value;
}

#ifndef HAVE_ARM_EHABI_EXCEPTIONS
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







-
+







			if (classMatches(class, e->object)) {
				*filterPtr = filter;
				return HANDLER_FOUND;
			}
		} else if (filter == 0)
			return CLEANUP_FOUND;
		else if (filter < 0)
			OBJC_ERROR("Invalid filter!")
			OBJC_ERROR("Invalid filter!");
	} while (displacement != 0);

	return 0;
}

#ifdef HAVE_SEH_EXCEPTIONS
static
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
718
719
720
721
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
737
738
739
740
741
742
743
744

745
746
747
748
749
750

751
752
753
754
755
756
757
758
759
760
761
762

763
764
765
766
767
768
769
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
718
719
720
721
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
737
738
739
740
741
742
743
744

745
746
747
748
749
750

751
752
753
754
755
756
757
758
759
760
761
762

763
764
765
766
767
768
769
770







+
-
+













-
+






-
+












-
+














-
+





-
+











-
+







		    (uintptr_t)ex);
		_Unwind_SetGR(ctx, __builtin_eh_return_data_regno(1), filter);
		_Unwind_SetIP(ctx, landingpad);

		return _URC_INSTALL_CONTEXT;
	}

	OBJC_ERROR(
	OBJC_ERROR("Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE in actions!")
	    "Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE in actions!");
}

static void
cleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception *ex)
{
	free(ex);
}

static void
emergencyExceptionCleanup(_Unwind_Reason_Code reason,
    struct _Unwind_Exception *ex)
{
#ifdef OF_HAVE_THREADS
	if (!of_spinlock_lock(&emergencyExceptionsSpinlock))
	if (of_spinlock_lock(&emergencyExceptionsSpinlock) != 0)
		OBJC_ERROR("Cannot lock spinlock!");
#endif

	ex->class = 0;

#ifdef OF_HAVE_THREADS
	if (!of_spinlock_unlock(&emergencyExceptionsSpinlock))
	if (of_spinlock_unlock(&emergencyExceptionsSpinlock) != 0)
		OBJC_ERROR("Cannot unlock spinlock!");
#endif
}

void
objc_exception_throw(id object)
{
	struct objc_exception *e = calloc(1, sizeof(*e));
	bool emergency = false;

	if (e == NULL) {
#ifdef OF_HAVE_THREADS
		if (!of_spinlock_lock(&emergencyExceptionsSpinlock))
		if (of_spinlock_lock(&emergencyExceptionsSpinlock) != 0)
			OBJC_ERROR("Cannot lock spinlock!");
#endif

		for (uint_fast8_t i = 0; i < NUM_EMERGENCY_EXCEPTIONS; i++) {
			if (emergencyExceptions[i].exception.class == 0) {
				e = &emergencyExceptions[i];
				e->exception.class = GNUCOBJC_EXCEPTION_CLASS;
				emergency = true;

				break;
			}
		}

#ifdef OF_HAVE_THREADS
		if (!of_spinlock_unlock(&emergencyExceptionsSpinlock))
		if (of_spinlock_unlock(&emergencyExceptionsSpinlock) != 0)
			OBJC_ERROR("Cannot lock spinlock!");
#endif
	}

	if (e == NULL)
		OBJC_ERROR("Not enough memory to allocate exception!")
		OBJC_ERROR("Not enough memory to allocate exception!");

	e->exception.class = GNUCOBJC_EXCEPTION_CLASS;
	e->exception.cleanup = (emergency
	    ? emergencyExceptionCleanup : cleanup);
	e->object = object;

	_Unwind_RaiseException(&e->exception);

	if (uncaughtExceptionHandler != NULL)
		uncaughtExceptionHandler(object);

	OBJC_ERROR("_Unwind_RaiseException() returned!")
	OBJC_ERROR("_Unwind_RaiseException() returned!");
}

objc_uncaught_exception_handler_t
objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler_t handler)
{
	objc_uncaught_exception_handler_t old = uncaughtExceptionHandler;
	uncaughtExceptionHandler = handler;

Modified src/runtime/linklib/linklib.m from [99c78c6a65] to [32b1f9e0eb].

18
19
20
21
22
23
24

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

31
32
33
34
35
36
37







+





-







#include "config.h"

#import "ObjFWRT.h"
#import "private.h"
#import "macros.h"

#include <proto/exec.h>
#include <proto/intuition.h>

struct ObjFWRTBase;

#import "inline.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

#if defined(OF_AMIGAOS_M68K)
# include <stabs.h>
# define SYM(name) __asm__("_" name)
#elif defined(OF_MORPHOS)
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
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







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











-
-
-







extern void __register_frame(void *);
extern void __deregister_frame(void *);
#endif

struct Library *ObjFWRTBase;
void *__objc_class_name_Protocol;

static int *
get_errno(void)
{
	return &errno;
static void
error(const char *string, ULONG arg)
{
	struct Library *IntuitionBase = OpenLibrary("intuition.library", 0);

	if (IntuitionBase != NULL) {
		struct EasyStruct easy = {
			.es_StructSize = sizeof(easy),
			.es_Flags = 0,
			.es_Title = (void *)NULL,
			.es_TextFormat = (void *)string,
			(void *)"OK"
		};

		EasyRequest(NULL, &easy, NULL, arg);

		CloseLibrary(IntuitionBase);
	}

	exit(EXIT_FAILURE);
}

static void __attribute__((__used__))
ctor(void)
{
	static bool initialized = false;
	struct objc_libc libc = {
		.malloc = malloc,
		.calloc = calloc,
		.realloc = realloc,
		.free = free,
		.vfprintf = vfprintf,
		.fflush = fflush,
		.abort = abort,
#ifdef HAVE_SJLJ_EXCEPTIONS
		._Unwind_SjLj_RaiseException = _Unwind_SjLj_RaiseException,
#else
		._Unwind_RaiseException = _Unwind_RaiseException,
#endif
		._Unwind_DeleteException = _Unwind_DeleteException,
		._Unwind_GetLanguageSpecificData =
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
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







+
+
+
+
-
+






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







		.__register_frame_info = __register_frame_info,
		.__deregister_frame_info = __deregister_frame_info,
#endif
#ifdef OF_MORPHOS
		.__register_frame = __register_frame,
		.__deregister_frame = __deregister_frame,
#endif
#ifdef OF_AMIGAOS_M68K
		.vsnprintf = vsnprintf,
#endif
		.atexit = atexit,
		.get_errno = get_errno,
		.exit = exit,
	};

	if (initialized)
		return;

	if ((ObjFWRTBase = OpenLibrary(OBJFWRT_AMIGA_LIB,
	    OBJFWRT_LIB_MINOR)) == NULL) {
		fputs("Failed to open " OBJFWRT_AMIGA_LIB "!\n", stderr);
		abort();
	}
	    OBJFWRT_LIB_MINOR)) == NULL)
		error("Failed to open " OBJFWRT_AMIGA_LIB " version %lu!",
		    OBJFWRT_LIB_MINOR);


	if (!glue_objc_init(1, &libc, stdout, stderr)) {
		fputs("Failed to initialize " OBJFWRT_AMIGA_LIB "!\n", stderr);
	if (!glue_objc_init(1, &libc))
		error("Failed to initialize " OBJFWRT_AMIGA_LIB "!", 0);
		abort();
	}

	initialized = true;
}

static void __attribute__((__used__))
dtor(void)
{

Modified src/runtime/misc.m from [a61bf65bf6] to [5ec6e3911d].

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














































































13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135







+





+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

#include "ObjFWRT.h"
#include "private.h"

#ifdef OF_WINDOWS
# include <windows.h>
#endif

#ifdef OF_AMIGAOS
# define USE_INLINE_STDARG
# include <proto/exec.h>
# include <clib/debug_protos.h>
# define __NOLIBBASE__
# define Class IntuitionClass
# include <proto/intuition.h>
# undef Class
# undef __NOLIBBASE__
#endif

static objc_enumeration_mutation_handler_t enumerationMutationHandler = NULL;

void
objc_enumerationMutation(id object)
{
	if (enumerationMutationHandler != NULL)
		enumerationMutationHandler(object);
	else
		OBJC_ERROR("Object was mutated during enumeration!");
}

void
objc_setEnumerationMutationHandler(objc_enumeration_mutation_handler_t handler)
{
	enumerationMutationHandler = handler;
}

void
objc_error(const char *title, const char *format, ...)
{
#if defined(OF_WINDOWS) || defined(OF_AMIGAOS)
# define BUF_LEN 512
	char message[BUF_LEN];
	int status;
	va_list args;

	va_start(args, format);
	status = vsnprintf(message, BUF_LEN, format, args);
	if (status <= 0 || status >= BUF_LEN)
		message[0] = '\0';
	va_end(args);
# undef BUF_LEN
#endif

#if defined(OF_WINDOWS)
	fprintf(stderr, "[%s] %s\n", title, message);
	fflush(stderr);

	MessageBoxA(NULL, message, title,
	    MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);

	exit(EXIT_FAILURE);
#elif defined(OF_AMIGAOS)
	struct Library *IntuitionBase;
# ifdef OF_AMIGAOS4
	struct IntuitionIFace *IIntuition;
# endif
	struct EasyStruct easy;

# ifndef OF_AMIGAOS4
	kprintf("[%s] %s\n", title, message);
# endif

	if ((IntuitionBase = OpenLibrary("intuition.library", 0)) == NULL)
		exit(EXIT_FAILURE);

# ifdef OF_AMIGAOS4
	if ((IIntuition = (struct IntuitionIFace *)GetInterface(IntuitionBase,
	    "main", 1, NULL)) == NULL)
		exit(EXIT_FAILURE);
# endif

	easy.es_StructSize = sizeof(easy);
	easy.es_Flags = 0;
	easy.es_Title = (void *)title;
	easy.es_TextFormat = (void *)"%s";
	easy.es_GadgetFormat = (void *)"OK";

	EasyRequest(NULL, &easy, NULL, (ULONG)message);

# ifdef OF_AMIGAOS4
	DropInterface((struct Interface *)IIntuition);
# endif

	CloseLibrary(IntuitionBase);

	exit(EXIT_FAILURE);
#else
	va_list args;

	va_start(args, format);

	fprintf(stderr, "[%s] ", title);
	vfprintf(stderr, format, args);
	fprintf(stderr, "\n");
	fflush(stderr);

	va_end(args);

	abort();
#endif

	OF_UNREACHABLE
}

Modified src/runtime/morphos-clib.h from [8a12dfceaa] to [750cbb9d7c].

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/* The following function is only for the linklib. */
bool glue_objc_init(unsigned int, struct objc_libc *, FILE *, FILE *);
bool glue_objc_init(unsigned int, struct objc_libc *);
void glue___objc_exec_class(struct objc_module *);
IMP glue_objc_msg_lookup(id, SEL);
IMP glue_objc_msg_lookup_stret(id, SEL);
IMP glue_objc_msg_lookup_super(struct objc_super *, SEL);
IMP glue_objc_msg_lookup_super_stret(struct objc_super *, SEL);
Class glue_objc_lookUpClass(const char *);
Class glue_objc_getClass(const char *);

Modified src/runtime/morphos.fd from [f88311d1a0] to [4a176c28f2].

1
2
3
4
5

6
7
8
9
10
11
12
1
2
3
4

5
6
7
8
9
10
11
12




-
+







##base _ObjFWRTBase
##bias 30
##public
* The following function is only for the linklib.
glue_objc_init(version,libc,stdout,stderr)(sysv,r12base)
glue_objc_init(version,libc)(sysv,r12base)
glue___objc_exec_class(module)(sysv,r12base)
glue_objc_msg_lookup(object,selector)(sysv,r12base)
glue_objc_msg_lookup_stret(object,selector)(sysv,r12base)
glue_objc_msg_lookup_super(super,selector)(sysv,r12base)
glue_objc_msg_lookup_super_stret(super,selector)(sysv,r12base)
glue_objc_lookUpClass(name)(sysv,r12base)
glue_objc_getClass(name)(sysv,r12base)

Modified src/runtime/private.h from [21af80272e] to [db00c9b1c3].

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
221
222
223
224
225
226
227



228
229
230
231
232
233
234







-
-
-







#if defined(OBJC_COMPILING_AMIGA_LIBRARY) || \
    defined(OBJC_COMPILING_AMIGA_LINKLIB)
struct objc_libc {
	void *_Nullable (*_Nonnull malloc)(size_t);
	void *_Nullable (*_Nonnull calloc)(size_t, size_t);
	void *_Nullable (*_Nonnull realloc)(void *_Nullable, size_t);
	void (*_Nonnull free)(void *_Nullable);
	int (*_Nonnull vfprintf)(FILE *_Nonnull, const char *_Nonnull, va_list);
	int (*_Nonnull fflush)(FILE *_Nonnull);
	void (*_Nonnull abort)(void);
# ifdef HAVE_SJLJ_EXCEPTIONS
	int (*_Nonnull _Unwind_SjLj_RaiseException)(void *_Nonnull);
# else
	int (*_Nonnull _Unwind_RaiseException)(void *_Nonnull);
# endif
	void (*_Nonnull _Unwind_DeleteException)(void *_Nonnull);
	void *_Nullable (*_Nonnull _Unwind_GetLanguageSpecificData)(
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
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







+
+
+
+
+
-
+












-
-
-
-
-
-







	    void *_Nonnull);
	void *(*_Nonnull __deregister_frame_info)(const void *_Nonnull);
# endif
# ifdef OF_MORPHOS
	void (*_Nonnull __register_frame)(void *_Nonnull);
	void (*_Nonnull __deregister_frame)(void *_Nonnull);
# endif
# ifdef OF_AMIGAOS_M68K
	int (*_Nonnull vsnprintf)(char *restrict _Nonnull str, size_t size,
	    const char *_Nonnull restrict fmt, va_list args);
# endif
	int (*_Nonnull atexit)(void (*_Nonnull)(void));
	int *_Nonnull (*_Nonnull get_errno)(void);
	void (*_Nonnull exit)(int);
};
#endif

#ifdef OBJC_COMPILING_AMIGA_LIBRARY
# if defined(__MORPHOS__)
#  include <ppcinline/macros.h>
#  define OBJC_M68K_ARG(type, name, reg) type name = (type)REG_##reg;
# else
#  define OBJC_M68K_ARG(type, name, reg)	\
	register type reg_##name __asm__(#reg);	\
	type name = reg_##name;
# endif
# undef stdout
# undef stderr
# undef errno
extern FILE *_Nonnull stdout, *_Nonnull stderr;
extern int *_Nonnull objc_get_errno(void);
# define errno (*objc_get_errno())
#endif

extern void objc_register_all_categories(struct objc_symtab *_Nonnull);
extern struct objc_category *_Nullable *_Nullable
    objc_categories_for_class(Class _Nonnull);
extern void objc_unregister_all_categories(void);
extern void objc_initialize_class(Class _Nonnull);
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
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







+
+
+
+
+
+














-
-
-
-
-
-
-
-
-
-







#else
	uint8_t i = idx >> 8;
	uint8_t j = idx;

	return dtable->buckets[i]->buckets[j];
#endif
}

extern void OF_NO_RETURN_FUNC objc_error(const char *_Nonnull title,
    const char *_Nonnull format, ...);
#define OBJC_ERROR(...)							\
	objc_error("ObjFWRT @ " __FILE__ ":" OF_STRINGIFY(__LINE__),	\
	    __VA_ARGS__)

#if defined(OF_ELF)
# if defined(OF_X86_64) || defined(OF_X86) || defined(OF_POWERPC) || \
    defined(OF_ARM64) || defined(OF_ARM) || \
    defined(OF_MIPS64_N64) || defined(OF_MIPS) || \
    defined(OF_SPARC64) || defined(OF_SPARC)
#  define OF_ASM_LOOKUP
# endif
#elif defined(OF_WINDOWS)
# if defined(OF_X86_64) || defined(OF_X86)
#  define OF_ASM_LOOKUP
# endif
#endif

#define OBJC_ERROR(...)							\
	{								\
		fprintf(stderr, "[objc @ " __FILE__ ":%d] ", __LINE__);	\
		fprintf(stderr, __VA_ARGS__);				\
		fprintf(stderr, "\n");					\
		fflush(stderr);						\
		abort();						\
		OF_UNREACHABLE						\
	}

@interface DummyObject
{
	Class _Nonnull isa;
}

@property (readonly, nonatomic) bool allowsWeakReference;

Modified src/runtime/property.m from [f51e3c1883] to [ead25184a1].

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







-
-
+
+











-
+



-
+


















-
+


















-
+







static of_spinlock_t spinlocks[NUM_SPINLOCKS];
#endif

#ifdef OF_HAVE_THREADS
OF_CONSTRUCTOR()
{
	for (size_t i = 0; i < NUM_SPINLOCKS; i++)
		if (!of_spinlock_new(&spinlocks[i]))
			OBJC_ERROR("Failed to initialize spinlocks!")
		if (of_spinlock_new(&spinlocks[i]) != 0)
			OBJC_ERROR("Failed to initialize spinlocks!");
}
#endif

id
objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, bool atomic)
{
	if (atomic) {
		id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0);
		@try {
			return [[*ptr retain] autorelease];
		} @finally {
			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0);
		}
#else
		return [[*ptr retain] autorelease];
#endif
	}

	return *(id *)(void *)((char *)self + offset);
}

void
objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, bool atomic,
    signed char copy)
{
	if (atomic) {
		id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0);
		@try {
#endif
			id old = *ptr;

			switch (copy) {
			case 0:
				*ptr = [value retain];
				break;
			case 2:
				*ptr = [value mutableCopy];
				break;
			default:
				*ptr = [value copy];
			}

			[old release];
#ifdef OF_HAVE_THREADS
		} @finally {
			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0);
		}
#endif

		return;
	}

	id *ptr = (id *)(void *)((char *)self + offset);
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
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







-
+



-
+
















-
+



-
+







objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic,
    bool strong)
{
	if (atomic) {
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0);
#endif
		memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0);
#endif

		return;
	}

	memcpy(dest, src, size);
}

void
objc_setPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic,
    bool strong)
{
	if (atomic) {
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(src);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0);
#endif
		memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
		OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0);
#endif

		return;
	}

	memcpy(dest, src, size);
}

Modified src/runtime/synchronized.m from [dcf43cf9c5] to [8b8ee09700].

33
34
35
36
37
38
39
40
41


42
43
44
45
46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64

65
66
67

68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86

87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114

115
116
117
118

119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
33
34
35
36
37
38
39


40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63

64
65
66

67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85

86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113

114
115
116
117

118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139







-
-
+
+












-
+









-
+


-
+









-
+








-
+


-
+















-
+








-
+



-
+










-
+










	struct lock_s *next;
} *locks = NULL;

static of_mutex_t mutex;

OF_CONSTRUCTOR()
{
	if (!of_mutex_new(&mutex))
		OBJC_ERROR("Failed to create mutex!")
	if (of_mutex_new(&mutex) != 0)
		OBJC_ERROR("Failed to create mutex!");
}
#endif

int
objc_sync_enter(id object)
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock_s *lock;

	if (!of_mutex_lock(&mutex))
	if (of_mutex_lock(&mutex) != 0)
		OBJC_ERROR("Failed to lock mutex!");

	/* Look if we already have a lock */
	for (lock = locks; lock != NULL; lock = lock->next) {
		if (lock->object != object)
			continue;

		lock->count++;

		if (!of_mutex_unlock(&mutex))
		if (of_mutex_unlock(&mutex) != 0)
			OBJC_ERROR("Failed to unlock mutex!");

		if (!of_rmutex_lock(&lock->rmutex))
		if (of_rmutex_lock(&lock->rmutex) != 0)
			OBJC_ERROR("Failed to lock mutex!");

		return 0;
	}

	/* Create a new lock */
	if ((lock = malloc(sizeof(*lock))) == NULL)
		OBJC_ERROR("Failed to allocate memory for mutex!");

	if (!of_rmutex_new(&lock->rmutex))
	if (of_rmutex_new(&lock->rmutex) != 0)
		OBJC_ERROR("Failed to create mutex!");

	lock->object = object;
	lock->count = 1;
	lock->next = locks;

	locks = lock;

	if (!of_mutex_unlock(&mutex))
	if (of_mutex_unlock(&mutex) != 0)
		OBJC_ERROR("Failed to unlock mutex!");

	if (!of_rmutex_lock(&lock->rmutex))
	if (of_rmutex_lock(&lock->rmutex) != 0)
		OBJC_ERROR("Failed to lock mutex!");
#endif

	return 0;
}

int
objc_sync_exit(id object)
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock_s *lock, *last = NULL;

	if (!of_mutex_lock(&mutex))
	if (of_mutex_lock(&mutex) != 0)
		OBJC_ERROR("Failed to lock mutex!");

	for (lock = locks; lock != NULL; lock = lock->next) {
		if (lock->object != object) {
			last = lock;
			continue;
		}

		if (!of_rmutex_unlock(&lock->rmutex))
		if (of_rmutex_unlock(&lock->rmutex) != 0)
			OBJC_ERROR("Failed to unlock mutex!");

		if (--lock->count == 0) {
			if (!of_rmutex_free(&lock->rmutex))
			if (of_rmutex_free(&lock->rmutex) != 0)
				OBJC_ERROR("Failed to destroy mutex!");

			if (last != NULL)
				last->next = lock->next;
			if (locks == lock)
				locks = lock->next;

			free(lock);
		}

		if (!of_mutex_unlock(&mutex))
		if (of_mutex_unlock(&mutex) != 0)
			OBJC_ERROR("Failed to unlock mutex!");

		return 0;
	}

	OBJC_ERROR("objc_sync_exit() was called for an object not locked!");
#else
	return 0;
#endif
}

Modified src/runtime/threading.m from [e792c643b3] to [4a1cc07735].

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







-
+









-
+






-
+


#import "once.h"

static of_rmutex_t globalMutex;

static void
init(void)
{
	if (!of_rmutex_new(&globalMutex))
	if (of_rmutex_new(&globalMutex) != 0)
		OBJC_ERROR("Failed to create global mutex!");
}

void
objc_global_mutex_lock(void)
{
	static of_once_t once_control = OF_ONCE_INIT;
	of_once(&once_control, init);

	if (!of_rmutex_lock(&globalMutex))
	if (of_rmutex_lock(&globalMutex) != 0)
		OBJC_ERROR("Failed to lock global mutex!");
}

void
objc_global_mutex_unlock(void)
{
	if (!of_rmutex_unlock(&globalMutex))
	if (of_rmutex_unlock(&globalMutex) != 0)
		OBJC_ERROR("Failed to unlock global mutex!");
}

Modified src/socket.h from [a0b49c9437] to [91d122f865].

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
77
78
79
80
81
82
83




84
85
86
87
88
89
90







-
-
-
-








#ifdef OF_MORPHOS
typedef long socklen_t;
typedef u_char sa_family_t;
typedef u_short in_port_t;
#endif

#ifdef OF_MORPHOS_IXEMUL
typedef int socklen_t;
#endif

/**
 * @brief A socket address family.
 */
typedef enum {
	/** An unknown address family. */
	OF_SOCKET_ADDRESS_FAMILY_UNKNOWN,
	/** IPv4 */

Modified src/socket.m from [d03343d8fd] to [d886e134b6].

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







+
+
+












-
-
-
-
+
-













+
+
-
+
+
+
+
+







#endif

#include <errno.h>

#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFLocale.h"
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
#endif
#import "OFString.h"

#import "OFException.h"  /* For some E* -> WSAE* defines */
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFLockFailedException.h"
#import "OFUnlockFailedException.h"

#import "socket.h"
#import "socket_helpers.h"
#ifdef OF_HAVE_THREADS
# if !defined(OF_AMIGAOS) || defined(OF_MORPHOS)
#  import "mutex.h"
# else
#  import "tlskey.h"
# import "tlskey.h"
# endif
#endif
#import "once.h"

#ifdef OF_AMIGAOS
# include <proto/exec.h>
#endif

#ifdef OF_NINTENDO_3DS
# include <3ds/types.h>
# include <3ds/services/soc.h>
#endif

#if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS))
static OFMutex *mutex;

static of_mutex_t mutex;
static void
releaseMutex(void)
{
	[mutex release];
}
#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)
75
76
77
78
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
95
96
97
98







-
+



-
+







#  endif
# endif
#endif

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

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

#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static void
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
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







-
-
+
+


-
+







-


+







-

+







	if (socInit(ctx, 0x100000) != 0)
		return;

	atexit((void (*)(void))socExit);
# endif

# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS))
	if (!of_mutex_new(&mutex))
		return;
	mutex = [[OFMutex alloc] init];
	atexit(releaseMutex);

#  ifdef OF_WII
	if (!of_spinlock_new(&spinlock))
	if (of_spinlock_new(&spinlock) != 0)
		return;
#  endif
# endif

	initSuccessful = true;
}

# ifdef OF_AMIGAOS
OF_DESTRUCTOR()
{
# ifdef OF_AMIGAOS
#  ifdef OF_AMIGAOS4
	if (ISocket != NULL)
		DropInterface((struct Interface *)ISocket);
#  endif

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

bool
of_socket_init(void)
{
#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
	static of_once_t onceControl = OF_ONCE_INIT;
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
184
185
186
187
188
189
190

191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
207







-
+








-
+







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

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

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

	return true;
325
326
327
328
329
330
331
332
333
334

335
336
337
338
339
340

341
342
343
344
345
346
347
348
330
331
332
333
334
335
336



337
338

339

340

341

342
343
344
345
346
347
348







-
-
-
+

-

-

-
+
-







int
of_getsockname(of_socket_t sock, struct sockaddr *restrict addr,
    socklen_t *restrict addrLen)
{
	int ret;

# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS))
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	[mutex lock];
# endif

	ret = getsockname(sock, addr, addrLen);

# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS))
	if (!of_mutex_unlock(&mutex))
	[mutex unlock];
		@throw [OFUnlockFailedException exception];
# endif

	return ret;
}
#endif

of_socket_address_t

Modified src/socket_helpers.h from [c2b374f2db] to [518711966a].

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




76
77
78
79
80
81
82







-
-
-
-







# ifdef OF_MORPHOS
typedef uint32_t in_addr_t;
# endif
#elif !defined(OF_WINDOWS) && !defined(OF_WII)
# define closesocket(sock) close(sock)
#endif

#ifdef OF_MORPHOS_IXEMUL
typedef uint32_t in_addr_t;
#endif

#ifdef OF_WII
# define accept(sock, addr, addrlen) net_accept(sock, addr, addrlen)
# define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen)
# define closesocket(sock) net_close(sock)
# define connect(sock, addr, addrlen) \
    net_connect(sock, (struct sockaddr *)addr, addrlen)
# define fcntl(fd, cmd, flags) net_fcntl(fd, cmd, flags)

Modified src/thread.h from [bf84b7cea6] to [821c6c8243].

61
62
63
64
65
66
67
68
69


70
71
72
73


74
75
76
61
62
63
64
65
66
67


68
69
70
71


72
73
74
75
76







-
-
+
+


-
-
+
+



# define of_thread_is_current(t) (t->thread == FindTask(NULL))
extern of_thread_t of_thread_current(void);
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern bool of_thread_attr_init(of_thread_attr_t *attr);
extern bool of_thread_new(of_thread_t *thread, const char *name,
extern int of_thread_attr_init(of_thread_attr_t *attr);
extern int of_thread_new(of_thread_t *thread, const char *name,
    void (*function)(id), id object, const of_thread_attr_t *attr);
extern void of_thread_set_name(const char *name);
extern bool of_thread_join(of_thread_t thread);
extern bool of_thread_detach(of_thread_t thread);
extern int of_thread_join(of_thread_t thread);
extern int of_thread_detach(of_thread_t thread);
#ifdef __cplusplus
}
#endif

Modified src/tlskey.h from [19e6f1fad4] to [bf467b6736].

12
13
14
15
16
17
18


19
20
21
22
23
24
25
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27







+
+







 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "objfw-defs.h"

#include <errno.h>

#include "platform.h"

#if !defined(OF_HAVE_THREADS) || \
    (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
# error No thread-local storage available!
#endif
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
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







-
-
+
+













-
+


-
+








-
+


-
+








-
+


-
+







-
+




	struct of_tlskey *next, *previous;
} *of_tlskey_t;
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern bool of_tlskey_new(of_tlskey_t *key);
extern bool of_tlskey_free(of_tlskey_t key);
extern int of_tlskey_new(of_tlskey_t *key);
extern int of_tlskey_free(of_tlskey_t key);
#ifdef __cplusplus
}
#endif

/* TLS keys are inlined for performance. */

#if defined(OF_HAVE_PTHREADS)
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
	return pthread_getspecific(key);
}

static OF_INLINE bool
static OF_INLINE int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
	return (pthread_setspecific(key, ptr) == 0);
	return pthread_setspecific(key, ptr);
}
#elif defined(OF_WINDOWS)
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
	return TlsGetValue(key);
}

static OF_INLINE bool
static OF_INLINE int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
	return TlsSetValue(key, ptr);
	return (TlsSetValue(key, ptr) ? 0 : EINVAL);
}
#elif defined(OF_MORPHOS)
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
	return (void *)TLSGetValue(key);
}

static OF_INLINE bool
static OF_INLINE int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
	return TLSSetValue(key, (APTR)ptr);
	return (TLSSetValue(key, (APTR)ptr) ? 0 : EINVAL);
}
#elif defined(OF_AMIGAOS)
/* Those are too big too inline. */
# ifdef __cplusplus
extern "C" {
# endif
extern void *of_tlskey_get(of_tlskey_t key);
extern bool of_tlskey_set(of_tlskey_t key, void *ptr);
extern int of_tlskey_set(of_tlskey_t key, void *ptr);
# ifdef __cplusplus
}
# endif
#endif

tests/OFIPXSocketTests.m became a regular file with contents [a065806b7f].

tests/OFSPXSocketTests.m became a regular file with contents [e438c57a59].

tests/OFSPXStreamSocketTests.m became a regular file with contents [4e87ecb1d0].

Modified tests/OFStringTests.m from [1ca0b0e0e8] to [484cb7d0ac].

22
23
24
25
26
27
28




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







+
+
+
+







#include <math.h>

#import "TestsAppDelegate.h"

#import "OFString.h"
#import "OFMutableUTF8String.h"
#import "OFUTF8String.h"

#ifndef INFINITY
# define INFINITY __builtin_inf()
#endif

static OFString *module = nil;
static OFString *whitespace[] = {
	@" \r \t\n\t \tasd  \t \t\t\r\n",
	@" \t\t  \t\t  \t \t"
};
static of_unichar_t ucstr[] = {
597
598
599
600
601
602
603
604




605
606
607
608
609
610
611
601
602
603
604
605
606
607

608
609
610
611
612
613
614
615
616
617
618







-
+
+
+
+







	    componentsSeparatedByString: @"XX"]) &&
	    [[a objectAtIndex: i++] isEqual: @"foo"] &&
	    [[a objectAtIndex: i++] isEqual: @"bar"] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @"baz"] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    a.count == i)
	    a.count == i &&
	    (a = [C(@"foo") componentsSeparatedByString: @""]) &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    a.count == 1)

	i = 0;
	TEST(@"-[componentsSeparatedByString:options:]",
	    (a = [C(@"fooXXbarXXXXbazXXXX")
	    componentsSeparatedByString: @"XX"
				options: OF_STRING_SKIP_EMPTY]) &&
	    [[a objectAtIndex: i++] isEqual: @"foo"] &&

Modified utils/ofhttp/OFHTTP.m from [8920dc599a] to [febf489eba].

62
63
64
65
66
67
68

69
70
71
72
73
74
75
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76







+







{
	OFArray OF_GENERIC(OFString *) *_URLs;
	size_t _URLIndex;
	int _errorCode;
	OFString *_outputPath, *_currentFileName;
	bool _continue, _force, _detectFileName, _detectFileNameRequest;
	bool _detectedFileName, _quiet, _verbose, _insecure, _ignoreStatus;
	bool _useUnicode;
	OFStream *_body;
	of_http_request_method_t _method;
	OFMutableDictionary *_clientHeaders;
	OFHTTPClient *_HTTPClient;
	char *_buffer;
	OFStream *_output;
	unsigned long long _received, _length, _resumedFrom;
573
574
575
576
577
578
579


580
581
582
583
584
585
586
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589







+
+







		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	if (_insecure)
		_HTTPClient.allowsInsecureRedirects = true;

	_useUnicode = ([OFLocale encoding] == OF_STRING_ENCODING_UTF_8);

	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}

-    (void)client: (OFHTTPClient *)client
  didCreateSocket: (OFTCPSocket *)sock
	  request: (OFHTTPRequest *)request
624
625
626
627
628
629
630
631
632






633
634
635
636
637
638
639
627
628
629
630
631
632
633


634
635
636
637
638
639
640
641
642
643
644
645
646







-
-
+
+
+
+
+
+







		    (object = [objectEnumerator nextObject]) != nil)
			[of_stdout writeFormat: @"  %@: %@\n",
						key, object];

		objc_autoreleasePoolPop(pool);
	}

	if (!_quiet)
		[of_stdout writeFormat: @"☇ %@", URL.string];
	if (!_quiet) {
		if (_useUnicode)
			[of_stdout writeFormat: @"☇ %@", URL.string];
		else
			[of_stdout writeFormat: @"< %@", URL.string];
	}

	_length = 0;

	return true;
}

-      (bool)stream: (OFStream *)response
706
707
708
709
710
711
712

713



714
715
716
717
718
719
720
713
714
715
716
717
718
719
720

721
722
723
724
725
726
727
728
729
730







+
-
+
+
+







		_resumedFrom = 0;

	if (!_quiet) {
		OFString *lengthString =
		    [headers objectForKey: @"Content-Length"];
		OFString *type = [headers objectForKey: @"Content-Type"];

		if (_useUnicode)
		[of_stdout writeFormat: @" ➜ %hd\n", statusCode];
			[of_stdout writeFormat: @" ➜ %hd\n", statusCode];
		else
			[of_stdout writeFormat: @" -> %hd\n", statusCode];

		if (type == nil)
			type = OF_LOCALIZED(@"type_unknown", @"unknown");

		if (lengthString != nil) {
			_length = lengthString.unsignedLongLongValue;

959
960
961
962
963
964
965
966


967
968
969
970
971
972
973
969
970
971
972
973
974
975

976
977
978
979
980
981
982
983
984







-
+
+







			goto next;
		}
	}

	if (!_quiet) {
		_progressBar = [[ProgressBar alloc]
		    initWithLength: _length
		       resumedFrom: _resumedFrom];
		       resumedFrom: _resumedFrom
			useUnicode: _useUnicode];
		[_progressBar setReceived: _received];
		[_progressBar draw];
	}

	[_currentFileName release];
	_currentFileName = nil;

1022
1023
1024
1025
1026
1027
1028
1029
1030






1031
1032
1033
1034
1035
1036
1037
1033
1034
1035
1036
1037
1038
1039


1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052







-
-
+
+
+
+
+
+







		_errorCode = 1;
		goto next;
	}

	clientHeaders = [[_clientHeaders mutableCopy] autorelease];

	if (_detectFileName && !_detectedFileName) {
		if (!_quiet)
			[of_stdout writeFormat: @"⠒ %@", URL.string];
		if (!_quiet) {
			if (_useUnicode)
				[of_stdout writeFormat: @"⠒ %@", URL.string];
			else
				[of_stdout writeFormat: @"? %@", URL.string];
		}

		request = [OFHTTPRequest requestWithURL: URL];
		request.headers = clientHeaders;
		request.method = OF_HTTP_REQUEST_METHOD_HEAD;

		_detectFileNameRequest = true;
		[_HTTPClient asyncPerformRequest: request];
1066
1067
1068
1069
1070
1071
1072
1073
1074






1075
1076
1077
1078
1079
1080
1081
1081
1082
1083
1084
1085
1086
1087


1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100







-
-
+
+
+
+
+
+







							    _resumedFrom];
			[clientHeaders setObject: range
					  forKey: @"Range"];
		} @catch (OFRetrieveItemAttributesFailedException *e) {
		}
	}

	if (!_quiet)
		[of_stdout writeFormat: @"⇣ %@", URL.string];
	if (!_quiet) {
		if (_useUnicode)
			[of_stdout writeFormat: @"⇣ %@", URL.string];
		else
			[of_stdout writeFormat: @"< %@", URL.string];
	}

	request = [OFHTTPRequest requestWithURL: URL];
	request.headers = clientHeaders;
	request.method = _method;

	_detectFileNameRequest = false;
	[_HTTPClient asyncPerformRequest: request];

Modified utils/ofhttp/ProgressBar.h from [187685081a] to [8f755a0177].

20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38


39
40
41
42
43
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







+











-
+
+





@class OFDate;
@class OFTimer;

#define BPS_WINDOW_SIZE 10

@interface ProgressBar: OFObject
{
	bool _useUnicode;
	unsigned long long _received, _lastReceived, _length, _resumedFrom;
	OFDate *_startDate, *_lastReceivedDate;
	OFTimer *_drawTimer, *_BPSTimer;
	bool _stopped;
	float _BPS;
	double _ETA;
	float _BPSWindow[BPS_WINDOW_SIZE];
	size_t _BPSWindowIndex, _BPSWindowLength;
}

- (instancetype)initWithLength: (unsigned long long)length
		   resumedFrom: (unsigned long long)resumedFrom;
		   resumedFrom: (unsigned long long)resumedFrom
		    useUnicode: (bool)useUnicode OF_DESIGNATED_INITIALIZER;
- (void)setReceived: (unsigned long long)received;
- (void)draw;
- (void)calculateBPSAndETA;
- (void)stop;
@end

Modified utils/ofhttp/ProgressBar.m from [814de8c246] to [8b9c4a1fb2].

31
32
33
34
35
36
37

38
39
40
41
42
43

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







+






+







#define KIBIBYTE (1024)

#define UPDATE_INTERVAL 0.1

@implementation ProgressBar
- (instancetype)initWithLength: (unsigned long long)length
		   resumedFrom: (unsigned long long)resumedFrom
		    useUnicode: (bool)useUnicode
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();

		_useUnicode = useUnicode;
		_length = length;
		_resumedFrom = resumedFrom;
		_startDate = [[OFDate alloc] init];
		_lastReceivedDate = [[OFDate alloc] init];
		_drawTimer = [[OFTimer
		    scheduledTimerWithTimeInterval: UPDATE_INTERVAL
					    target: self
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
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







+
-
+

-
-
-
-
+
+
+
+

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

-
-
-
+
+
+

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







		barWidth = 43;

	bars = (float)(_resumedFrom + _received) /
	    (float)(_resumedFrom + _length) * barWidth;
	percent = (float)(_resumedFrom + _received) /
	    (float)(_resumedFrom + _length) * 100;

	if (_useUnicode) {
	[of_stdout writeString: @"\r  ▕"];
		[of_stdout writeString: @"\r  ▕"];

	for (size_t i = 0; i < (size_t)bars; i++)
		[of_stdout writeString: @"█"];
	if (bars < barWidth) {
		float rem = bars - truncf(bars);
		for (size_t i = 0; i < (size_t)bars; i++)
			[of_stdout writeString: @"█"];
		if (bars < barWidth) {
			float rem = bars - truncf(bars);

		if (rem >= 0.875)
			[of_stdout writeString: @"▉"];
		else if (rem >= 0.75)
			[of_stdout writeString: @"▊"];
		else if (rem >= 0.625)
			[of_stdout writeString: @"▋"];
		else if (rem >= 0.5)
			[of_stdout writeString: @"▌"];
		else if (rem >= 0.375)
			[of_stdout writeString: @"▍"];
		else if (rem >= 0.25)
			[of_stdout writeString: @"▎"];
		else if (rem >= 0.125)
			[of_stdout writeString: @"▏"];
		else
			[of_stdout writeString: @" "];
			if (rem >= 0.875)
				[of_stdout writeString: @"▉"];
			else if (rem >= 0.75)
				[of_stdout writeString: @"▊"];
			else if (rem >= 0.625)
				[of_stdout writeString: @"▋"];
			else if (rem >= 0.5)
				[of_stdout writeString: @"▌"];
			else if (rem >= 0.375)
				[of_stdout writeString: @"▍"];
			else if (rem >= 0.25)
				[of_stdout writeString: @"▎"];
			else if (rem >= 0.125)
				[of_stdout writeString: @"▏"];
			else
				[of_stdout writeString: @" "];

		for (size_t i = 0; i < barWidth - (size_t)bars - 1; i++)
			[of_stdout writeString: @" "];
	}
			for (size_t i = 0; i < barWidth - (size_t)bars - 1; i++)
				[of_stdout writeString: @" "];
		}

	[of_stdout writeFormat: @"▏ %,6.2f%% ", percent];
		[of_stdout writeFormat: @"▏ %,6.2f%% ", percent];
	} else {
		[of_stdout writeString: @"\r  ["];

		for (size_t i = 0; i < (size_t)bars; i++)
			[of_stdout writeString: @"#"];
		if (bars < barWidth) {
			float rem = bars - truncf(bars);

			if (rem >= 0.75)
				[of_stdout writeString: @"O"];
			else if (rem >= 0.5)
				[of_stdout writeString: @"o"];
			else if (rem >= 0.25)
				[of_stdout writeString: @"."];
			else
				[of_stdout writeString: @" "];

			for (size_t i = 0; i < barWidth - (size_t)bars - 1; i++)
				[of_stdout writeString: @" "];
		}

		[of_stdout writeFormat: @"] %,6.2f%% ", percent];
	}

	if (percent == 100) {
		double timeInterval = -_startDate.timeIntervalSinceNow;

		_BPS = (float)_received / (float)timeInterval;
		_ETA = timeInterval;
	}