Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -51,12 +51,10 @@ AC_SUBST(AMIGA_LIB_LDFLAGS, "-mcpu=68020 -fbaserel -resident -nostartfiles") ]) ;; powerpc-*-amigaos*) - LIBS="$LIBS -lauto" - enable_shared="no" enable_threads="no" ;; *-morphos*) AS_IF([test x"$with_ixemul" != x"yes"], [ Index: src/OFApplication.m ================================================================== --- src/OFApplication.m +++ src/OFApplication.m @@ -52,11 +52,15 @@ #elif defined(OF_WINDOWS) # include extern int _CRT_glob; extern void __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); #elif defined(OF_AMIGAOS) -# define __USE_INLINE__ +# ifdef OF_AMIGAOS4 +# define __USE_INLINE__ +# define __NOLIBBASE__ +# define __NOGLOBALIFACE__ +# endif # include # include #elif !defined(OF_IOS) extern char **environ; #endif @@ -69,10 +73,14 @@ #ifdef OF_NINTENDO_DS # define asm __asm__ # include # undef asm #endif + +#ifdef OF_AMIGAOS4 +extern struct ExecIFace *IExec; +#endif @interface OFApplication () - (instancetype)of_init OF_METHOD_FAMILY(init); - (void)of_setArgumentCount: (int *)argc andArgumentValues: (char **[])argv; Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -56,11 +56,16 @@ # include # include #endif #ifdef OF_AMIGAOS -# define __USE_INLINE__ +# ifdef OF_AMIGAOS4 +# define __USE_INLINE__ +# define __NOLIBBASE__ +# define __NOGLOBALIFACE__ +# endif +# include # include #endif #ifndef O_BINARY # define O_BINARY 0 @@ -76,10 +81,16 @@ #endif #ifndef OF_AMIGAOS # define closeHandle(h) close(h) #else +# ifdef OF_AMIGAOS4 +extern struct ExecIFace *IExec; +static struct Library *DOSBase = NULL; +static struct DOSIFace *IDOS = NULL; +# endif + struct of_file_handle { of_file_handle_t previous, next; BPTR handle; bool append; } *firstHandle = NULL; @@ -103,10 +114,18 @@ OF_DESTRUCTOR() { for (of_file_handle_t iter = firstHandle; iter != NULL; iter = iter->next) Close(iter->handle); + +# ifdef OF_AMIGAOS4 + if (IDOS != NULL) + DropInterface(IDOS); + + if (DOSBase != NULL) + CloseLibrary(DOSBase); +# endif } #endif #ifndef OF_AMIGAOS static int @@ -177,10 +196,21 @@ #ifdef OF_NINTENDO_DS if (!nitroFSInit(NULL)) @throw [OFInitializationFailedException exceptionWithClass: self]; #endif + +#ifdef OF_AMIGAOS4 + if ((DOSBase = OpenLibrary("dos.library", 36)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; + + if ((IDOS = (struct DOSIFace *) + GetInterface(DOSBase, "main", 1, NULL)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +#endif } + (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode { Index: src/OFFileManager.m ================================================================== --- src/OFFileManager.m +++ src/OFFileManager.m @@ -40,10 +40,11 @@ #import "OFURLHandler.h" #import "OFChangeCurrentDirectoryPathFailedException.h" #import "OFCopyItemFailedException.h" #import "OFGetCurrentDirectoryPathFailedException.h" +#import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFMoveItemFailedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFRemoveItemFailedException.h" @@ -56,18 +57,28 @@ # include # include #endif #ifdef OF_AMIGAOS -# define __USE_INLINE__ +# ifdef OF_AMIGAOS4 +# define __USE_INLINE__ +# define __NOLIBBASE__ +# define __NOGLOBALIFACE__ +# endif # include # include # include #endif @interface OFFileManager_default: OFFileManager @end + +#ifdef OF_AMIGAOS4 +extern struct ExecIFace *IExec; +static struct Library *DOSBase = NULL; +static struct DOSIFace *IDOS = NULL; +#endif static OFFileManager *defaultManager; const of_file_attribute_key_t of_file_attribute_key_size = @"of_file_attribute_key_size"; @@ -107,10 +118,18 @@ OF_DESTRUCTOR() { if (dirChanged) UnLock(CurrentDir(originalDirLock)); + +# ifdef OF_AMIGAOS4 + if (IDOS != NULL) + DropInterface(IDOS); + + if (DOSBase != NULL) + CloseLibrary(DOSBase); +# endif } #endif static id attributeForKeyOrException(of_file_attributes_t attributes, @@ -128,10 +147,21 @@ @implementation OFFileManager + (void)initialize { if (self != [OFFileManager class]) return; + +#ifdef OF_AMIGAOS4 + if ((DOSBase = OpenLibrary("dos.library", 36)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; + + if ((IDOS = (struct DOSIFace *) + GetInterface(DOSBase, "main", 1, NULL)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +#endif defaultManager = [[OFFileManager_default alloc] init]; } + (OFFileManager *)defaultManager Index: src/OFLocale.m ================================================================== --- src/OFLocale.m +++ src/OFLocale.m @@ -28,17 +28,44 @@ #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFOpenItemFailedException.h" #ifdef OF_AMIGAOS -# define __USE_INLINE__ +# ifdef OF_AMIGAOS4 +# define __NOLIBBASE__ +# define __NOGLOBALIFACE__ +# define __USE_INLINE__ +# endif # include # include # include #endif static OFLocale *currentLocale = nil; + +#ifdef OF_AMIGAOS4 +extern struct ExecIFace *IExec; +static struct Library *DOSBase = NULL; +static struct DOSIFace *IDOS = NULL; +static struct Library *LocaleBase = NULL; +static struct LocaleIFace *ILocale = NULL; + +OF_DESTRUCTOR() +{ + if (ILocale != NULL) + DropInterface(ILocale); + + if (LocaleBase != NULL) + CloseLibrary(LocaleBase); + + if (IDOS != NULL) + DropInterface(IDOS); + + if (DOSBase != NULL) + CloseLibrary(DOSBase); +} +#endif #ifndef OF_AMIGAOS static void parseLocale(char *locale, of_string_encoding_t *encoding, OFString **language, OFString **territory) Index: src/OFStdIOStream.m ================================================================== --- src/OFStdIOStream.m +++ src/OFStdIOStream.m @@ -34,17 +34,22 @@ #import "OFApplication.h" #ifdef OF_WINDOWS # include "OFStdIOStream_Win32Console.h" #endif +#import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #ifdef OF_AMIGAOS -# define __USE_INLINE__ +# ifdef OF_AMIGAOS4 +# define __USE_INLINE__ +# define __NOLIBBASE__ +# define __NOGLOBALIFACE__ +# endif # include # include #endif /* References for static linking */ @@ -53,10 +58,16 @@ _reference_to_OFStdIOStream_Win32Console(void) { [OFStdIOStream_Win32Console class]; } #endif + +#ifdef OF_AMIGAOS4 +extern struct ExecIFace *IExec; +static struct Library *DOSBase = NULL; +static struct DOSIFace *IDOS = NULL; +#endif OFStdIOStream *of_stdin = nil; OFStdIOStream *of_stdout = nil; OFStdIOStream *of_stderr = nil; @@ -64,10 +75,18 @@ OF_DESTRUCTOR() { [of_stdin dealloc]; [of_stdout dealloc]; [of_stderr dealloc]; + +# ifdef OF_AMIGAOS4 + if (IDOS != NULL) + DropInterface(IDOS); + + if (DOSBase != NULL) + CloseLibrary(DOSBase); +# endif } #endif void of_log(OFConstantString *format, ...) @@ -103,15 +122,29 @@ # ifndef OF_AMIGAOS of_stdin = [[OFStdIOStream alloc] of_initWithFileDescriptor: 0]; of_stdout = [[OFStdIOStream alloc] of_initWithFileDescriptor: 1]; of_stderr = [[OFStdIOStream alloc] of_initWithFileDescriptor: 2]; # else - BPTR input = Input(), output = Output(); - BPTR error = ((struct Process *)FindTask(NULL))->pr_CES; + BPTR input, output, error; bool inputClosable = false, outputClosable = false, errorClosable = false; +# ifdef OF_AMIGAOS4 + if ((DOSBase = OpenLibrary("dos.library", 36)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; + + if ((IDOS = (struct DOSIFace *) + GetInterface(DOSBase, "main", 1, NULL)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +# endif + + input = Input(); + output = Output(); + error = ((struct Process *)FindTask(NULL))->pr_CES; + if (input == 0) { input = Open("*", MODE_OLDFILE); inputClosable = true; } Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -31,11 +31,16 @@ #include "unistd_wrapper.h" #include "platform.h" #ifdef OF_AMIGAOS -# define __USE_INLINE__ +# ifdef OF_AMIGAOS4 +# define __USE_INLINE__ +# define __NOLIBBASE__ +# define __NOGLOBALIFACE__ +# endif +# include # include #endif #ifdef OF_WII # define nanosleep ogc_nanosleep @@ -85,10 +90,25 @@ #endif #ifdef OF_DJGPP # define lrint(x) rint(x) #endif + +#ifdef OF_AMIGAOS4 +extern struct ExecIFace *IExec; +static struct Library *DOSBase = NULL; +static struct DOSIFace *IDOS = NULL; + +OF_DESTRUCTOR() +{ + if (IDOS != NULL) + DropInterface(IDOS); + + if (DOSBase != NULL) + CloseLibrary(DOSBase); +} +#endif #if defined(OF_HAVE_THREADS) # import "threading.h" static of_tlskey_t threadSelfKey; @@ -186,10 +206,25 @@ if (thread->_threadDictionary == nil) thread->_threadDictionary = [[OFMutableDictionary alloc] init]; return thread->_threadDictionary; } +#elif defined(OF_AMIGAOS4) ++ (void)initialize +{ + if (self != [OFThread class]) + return; + + if ((DOSBase = OpenLibrary("dos.library", 36)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; + + if ((IDOS = (struct DOSIFace *) + GetInterface(DOSBase, "main", 1, NULL)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +} #endif #ifdef OF_HAVE_SOCKETS + (OFDNSResolver *)DNSResolver { Index: src/OFURLHandler_file.m ================================================================== --- src/OFURLHandler_file.m +++ src/OFURLHandler_file.m @@ -47,10 +47,11 @@ # import "OFMutex.h" #endif #import "OFCreateDirectoryFailedException.h" #import "OFCreateSymbolicLinkFailedException.h" +#import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFLinkFailedException.h" #import "OFMoveItemFailedException.h" #import "OFNotImplementedException.h" #import "OFOpenItemFailedException.h" @@ -65,11 +66,16 @@ # include # include #endif #ifdef OF_AMIGAOS -# define __USE_INLINE__ +# ifdef OF_AMIGAOS4 +# define __USE_INLINE__ +# define __NOLIBBASE__ +# define __NOGLOBALIFACE__ +# endif +# include # include # include # ifdef OF_AMIGAOS4 # define DeleteFile(path) Delete(path) # endif @@ -101,10 +107,33 @@ #endif #ifdef OF_WINDOWS static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD); #endif + +#ifdef OF_AMIGAOS4 +extern struct ExecIFace *IExec; +static struct Library *DOSBase = NULL; +static struct DOSIFace *IDOS = NULL; +static struct Library *LocaleBase = NULL; +static struct LocaleIFace *ILocale = NULL; + +OF_DESTRUCTOR() +{ + if (ILocale != NULL) + DropInterface(ILocale); + + if (LocaleBase != NULL) + CloseLibrary(LocaleBase); + + if (IDOS != NULL) + DropInterface(IDOS); + + if (DOSBase != NULL) + CloseLibrary(DOSBase); +} +#endif static int of_stat(OFString *path, of_stat_t *buffer) { #if defined(OF_WINDOWS) @@ -414,10 +443,30 @@ /* * Make sure OFFile is initialized. * On some systems, this is needed to initialize the file system driver. */ [OFFile class]; + +#ifdef OF_AMIGAOS4 + if ((DOSBase = OpenLibrary("dos.library", 36)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; + + if ((IDOS = (struct DOSIFace *) + GetInterface(DOSBase, "main", 1, NULL)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; + + if ((LocaleBase = OpenLibrary("locale.library", 38)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; + + if ((ILocale = (struct LocaleIFace *) + GetInterface(LocaleBase, "main", 1, NULL)) == NULL) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +#endif #if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) passwdMutex = [[OFMutex alloc] init]; #endif #if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS) Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -83,12 +83,17 @@ { #ifdef OF_PSP int tid; #endif -#if defined(OF_OBJFW_RUNTIME) && !defined(OF_WINDOWS) - /* This does not work on Win32 if ObjFW is built as a DLL */ +#if defined(OF_OBJFW_RUNTIME) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS4) + /* + * This does not work on Win32 if ObjFW is built as a DLL. + * + * On AmigaOS 4, atexit() calls objc_exit() before our destructors have + * run, but we need to send messages in some destructors. + */ atexit(objc_exit); #endif /* We need deterministic hashes for tests */ of_hash_seed = 0;