@@ -27,11 +27,11 @@ #import "copyright.h" @implementation LinkLibGenerator - (instancetype)initWithLibrary: (OFXMLElement *)library - outputStream: (OFStream *)outputStream + implementation: (OFStream *)impl { self = [super init]; @try { OFXMLAttribute *version; @@ -46,11 +46,11 @@ if (![version.stringValue isEqual: @"1.0"]) @throw [OFUnsupportedVersionException exceptionWithVersion: version.stringValue]; _library = [library retain]; - _outputStream = [outputStream retain]; + _impl = [impl retain]; } @catch (id e) { [self release]; @throw e; } @@ -58,11 +58,11 @@ } - (void)dealloc { [_library release]; - [_outputStream release]; + [_impl release]; [super dealloc]; } - (void)generate @@ -69,25 +69,25 @@ { OFString *libBase = [_library attributeForName: @"base"].stringValue; OFArray OF_GENERIC(OFXMLElement *) *functions; size_t funcIndex = 0; - [_outputStream writeString: COPYRIGHT]; - [_outputStream writeString: + [_impl writeString: COPYRIGHT]; + [_impl writeString: @"/* This file is automatically generated from library.xml */\n" @"\n" @"#include \"config.h\"\n" @"\n"]; for (OFXMLElement *include in [_library elementsForName: @"include"]) - [_outputStream writeFormat: @"#import \"%@\"\n", - include.stringValue]; + [_impl writeFormat: @"#import \"%@\"\n", + include.stringValue]; - [_outputStream writeFormat: @"\n" - @"extern struct Library *%@;\n" - @"\n", - libBase]; + [_impl writeFormat: @"\n" + @"extern struct Library *%@;\n" + @"\n", + libBase]; functions = [_library elementsForName: @"function"]; for (OFXMLElement *function in functions) { OFString *name = [function attributeForName: @"name"].stringValue; @@ -98,11 +98,11 @@ size_t argumentIndex; if (returnType == nil) returnType = @"void"; - [_outputStream writeFormat: @"%@\n%@(", returnType, name]; + [_impl writeFormat: @"%@\n%@(", returnType, name]; argumentIndex = 0; for (OFXMLElement *argument in [function elementsForName: @"argument"]) { OFString *argName = @@ -109,122 +109,120 @@ [argument attributeForName: @"name"].stringValue; OFString *argType = [argument attributeForName: @"type"].stringValue; if (argumentIndex++ > 0) - [_outputStream writeString: @", "]; + [_impl writeString: @", "]; - [_outputStream writeString: argType]; + [_impl writeString: argType]; if (![argType hasSuffix: @"*"]) - [_outputStream writeString: @" "]; - [_outputStream writeString: argName]; + [_impl writeString: @" "]; + [_impl writeString: argName]; } - [_outputStream writeFormat: + [_impl writeFormat: @")\n" @"{\n" @"#if defined(OF_AMIGAOS_M68K)\n" @"\tregister struct Library *a6 __asm__(\"a6\") = %@;\n" @"\t(void)a6;\n" @"\t", libBase]; if (![returnType isEqual: @"void"]) - [_outputStream writeString: @"return "]; + [_impl writeString: @"return "]; - [_outputStream writeString: @"(("]; - [_outputStream writeString: returnType]; + [_impl writeString: @"(("]; + [_impl writeString: returnType]; if (![returnType hasSuffix: @"*"]) - [_outputStream writeString: @" "]; - [_outputStream writeString: @"(*)("]; + [_impl writeString: @" "]; + [_impl writeString: @"(*)("]; argumentIndex = 0; for (OFXMLElement *argument in arguments) { OFString *argType = [argument attributeForName: @"type"].stringValue; OFString *m68kReg = [argument attributeForName: @"m68k-reg"].stringValue; if (argumentIndex++ > 0) - [_outputStream writeString: @", "]; + [_impl writeString: @", "]; - [_outputStream writeString: argType]; + [_impl writeString: argType]; if (![argType hasSuffix: @"*"]) - [_outputStream writeString: @" "]; - [_outputStream writeFormat: @"__asm__(\"%@\")", + [_impl writeString: @" "]; + [_impl writeFormat: @"__asm__(\"%@\")", m68kReg]; } - [_outputStream writeFormat: @"))(((uintptr_t)%@) - %zu))(", - libBase, 30 + funcIndex * 6]; + [_impl writeFormat: @"))(((uintptr_t)%@) - %zu))(", + libBase, 30 + funcIndex * 6]; argumentIndex = 0; for (OFXMLElement *argument in [function elementsForName: @"argument"]) { OFString *argName = [argument attributeForName: @"name"].stringValue; if (argumentIndex++ > 0) - [_outputStream writeString: @", "]; - - [_outputStream writeString: argName]; - } - - [_outputStream writeFormat: - @");\n" - @"#elif defined(OF_MORPHOS)\n" - @"\t__asm__ __volatile__ (\n" - @"\t \"mr\t\t%%%%r12, %%0\"\n" - @"\t :: \"r\"(%@) : \"r12\"\n" - @"\t);\n" - @"\n" - @"\t", - libBase, libBase]; + [_impl writeString: @", "]; + + [_impl writeString: argName]; + } + + [_impl writeFormat: @");\n" + @"#elif defined(OF_MORPHOS)\n" + @"\t__asm__ __volatile__ (\n" + @"\t \"mr\t\t%%%%r12, %%0\"\n" + @"\t :: \"r\"(%@) : \"r12\"\n" + @"\t);\n" + @"\n" + @"\t", + libBase, libBase]; if (![returnType isEqual: @"void"]) - [_outputStream writeString: @"return "]; + [_impl writeString: @"return "]; - [_outputStream writeString: @"__extension__ (("]; - [_outputStream writeString: returnType]; + [_impl writeString: @"__extension__ (("]; + [_impl writeString: returnType]; if (![returnType hasSuffix: @"*"]) - [_outputStream writeString: @" "]; - [_outputStream writeString: @"(*)("]; + [_impl writeString: @" "]; + [_impl writeString: @"(*)("]; argumentIndex = 0; for (OFXMLElement *argument in arguments) { OFString *argType = [argument attributeForName: @"type"].stringValue; if (argumentIndex++ > 0) - [_outputStream writeString: @", "]; + [_impl writeString: @", "]; - [_outputStream writeString: argType]; + [_impl writeString: argType]; } - [_outputStream writeFormat: - @"))*(void **)(((uintptr_t)%@) - %zu))(", - libBase, 28 + funcIndex * 6]; + [_impl writeFormat: @"))*(void **)(((uintptr_t)%@) - %zu))(", + libBase, 28 + funcIndex * 6]; argumentIndex = 0; for (OFXMLElement *argument in [function elementsForName: @"argument"]) { OFString *argName = [argument attributeForName: @"name"].stringValue; if (argumentIndex++ > 0) - [_outputStream writeString: @", "]; + [_impl writeString: @", "]; - [_outputStream writeString: argName]; + [_impl writeString: argName]; } - [_outputStream writeString: @");\n" - @"#endif\n"]; + [_impl writeString: @");\n" + @"#endif\n"]; if ([function attributeForName: @"noreturn"] != nil) - [_outputStream writeString: @"\n\tOF_UNREACHABLE\n"]; + [_impl writeString: @"\n\tOF_UNREACHABLE\n"]; - [_outputStream writeString: @"}\n"]; + [_impl writeString: @"}\n"]; if (++funcIndex < functions.count) - [_outputStream writeString: @"\n"]; + [_impl writeString: @"\n"]; } } @end