@@ -16,209 +16,40 @@ */ #include "config.h" #import "OFApplication.h" -#import "OFArray.h" #import "OFFile.h" -#import "OFXMLAttribute.h" +#import "OFFileManager.h" +#import "OFURL.h" #import "OFXMLElement.h" -#import "OFInvalidFormatException.h" -#import "OFUnsupportedVersionException.h" - -#import "copyright.h" +#import "LinkLibGenerator.h" @interface LibraryGenerator: OFObject @end OF_APPLICATION_DELEGATE(LibraryGenerator) @implementation LibraryGenerator -- (void)generateLinkLibInDirectory: (OFString *)directory -{ - OFXMLElement *library = [OFXMLElement elementWithFile: - [directory stringByAppendingPathComponent: @"library.xml"]]; - OFString *linklibPath = [[directory - stringByAppendingPathComponent: @"linklib"] - stringByAppendingPathComponent: @"linklib.m"]; - OFFile *linklib = [OFFile fileWithPath: linklibPath - mode: @"w"]; - OFArray OF_GENERIC(OFXMLElement *) *functions; - size_t funcIndex = 0; - OFString *libBase; - - if (![library.name isEqual: @"amiga-library"] || - library.namespace != nil) - @throw [OFInvalidFormatException exception]; - - OFXMLAttribute *version = [library attributeForName: @"version"]; - if (version == nil) - @throw [OFInvalidFormatException exception]; - - if (![version.stringValue isEqual: @"1.0"]) - @throw [OFUnsupportedVersionException - exceptionWithVersion: version.stringValue]; - - libBase = [library attributeForName: @"base"].stringValue; - - [linklib writeString: COPYRIGHT]; - [linklib writeString: - @"/* This file is automatically generated from library.xml */\n" - @"\n" - @"#include \"config.h\"\n" - @"\n"]; - - for (OFXMLElement *include in [library elementsForName: @"include"]) - [linklib writeFormat: @"#import \"%@\"\n", include.stringValue]; - - [linklib writeFormat: @"\n" - @"extern struct Library *%@;\n" - @"\n", - libBase]; - - functions = [library elementsForName: @"function"]; - for (OFXMLElement *function in functions) { - OFString *name = - [function attributeForName: @"name"].stringValue; - OFString *returnType = - [function attributeForName: @"return-type"].stringValue; - OFArray OF_GENERIC(OFXMLElement *) *arguments = - [function elementsForName: @"argument"]; - size_t argumentIndex; - - if (returnType == nil) - returnType = @"void"; - - [linklib writeFormat: @"%@\n%@(", returnType, name]; - - argumentIndex = 0; - for (OFXMLElement *argument in - [function elementsForName: @"argument"]) { - OFString *argName = - [argument attributeForName: @"name"].stringValue; - OFString *argType = - [argument attributeForName: @"type"].stringValue; - - if (argumentIndex++ > 0) - [linklib writeString: @", "]; - - [linklib writeString: argType]; - if (![argType hasSuffix: @"*"]) - [linklib writeString: @" "]; - [linklib writeString: argName]; - } - - [linklib 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"]) - [linklib writeString: @"return "]; - - [linklib writeString: @"(("]; - [linklib writeString: returnType]; - if (![returnType hasSuffix: @"*"]) - [linklib writeString: @" "]; - [linklib writeString: @"(*)("]; - - argumentIndex = 0; - for (OFXMLElement *argument in arguments) { - OFString *argType = - [argument attributeForName: @"type"].stringValue; - OFString *m68kReg = [argument - attributeForName: @"m68k-reg"].stringValue; - - if (argumentIndex++ > 0) - [linklib writeString: @", "]; - - [linklib writeString: argType]; - if (![argType hasSuffix: @"*"]) - [linklib writeString: @" "]; - [linklib writeFormat: @"__asm__(\"%@\")", m68kReg]; - } - - [linklib 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) - [linklib writeString: @", "]; - - [linklib writeString: argName]; - } - - [linklib 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"]) - [linklib writeString: @"return "]; - - [linklib writeString: @"__extension__ (("]; - [linklib writeString: returnType]; - if (![returnType hasSuffix: @"*"]) - [linklib writeString: @" "]; - [linklib writeString: @"(*)("]; - - argumentIndex = 0; - for (OFXMLElement *argument in arguments) { - OFString *argType = - [argument attributeForName: @"type"].stringValue; - - if (argumentIndex++ > 0) - [linklib writeString: @", "]; - - [linklib writeString: argType]; - } - - [linklib 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) - [linklib writeString: @", "]; - - [linklib writeString: argName]; - } - - [linklib writeString: @");\n" - @"#endif\n"]; - - if ([function attributeForName: @"noreturn"] != nil) - [linklib writeString: @"\n\tOF_UNREACHABLE\n"]; - - [linklib writeString: @"}\n"]; - - if (++funcIndex < functions.count) - [linklib writeString: @"\n"]; - } -} - - (void)applicationDidFinishLaunching { - [self generateLinkLibInDirectory: @"../../src/runtime"]; + OFURL *sourcesURL = [[OFFileManager defaultManager].currentDirectoryURL + URLByAppendingPathComponent: @"../../src"]; + OFURL *runtimeLibraryPath = [sourcesURL + URLByAppendingPathComponent: @"runtime/library.xml"]; + OFURL *runtimeLinkLibPath = [sourcesURL + URLByAppendingPathComponent: @"runtime/linklib/linklib.m"]; + OFXMLElement *runtimeLibrary = [OFXMLElement elementWithStream: + [OFFile fileWithURL: runtimeLibraryPath + mode: @"r"]]; + OFFile *runtimeLinkLib = [OFFile fileWithURL: runtimeLinkLibPath + mode: @"w"]; + LinkLibGenerator *runtimeLinkLibGenerator = [[[LinkLibGenerator alloc] + initWithLibrary: runtimeLibrary + outputStream: runtimeLinkLib] autorelease]; + + [runtimeLinkLibGenerator generate]; [OFApplication terminate]; } @end