@@ -27,11 +27,12 @@ #import "copyright.h" @implementation GlueGenerator - (instancetype)initWithLibrary: (OFXMLElement *)library - outputStream: (OFStream *)outputStream + header: (OFStream *)header + implementation: (OFStream *)impl { self = [super init]; @try { OFXMLAttribute *version; @@ -46,11 +47,12 @@ if (![version.stringValue isEqual: @"1.0"]) @throw [OFUnsupportedVersionException exceptionWithVersion: version.stringValue]; _library = [library retain]; - _outputStream = [outputStream retain]; + _header = [header retain]; + _impl = [impl retain]; } @catch (id e) { [self release]; @throw e; } @@ -58,29 +60,37 @@ } - (void)dealloc { [_library release]; - [_outputStream release]; + [_header release]; + [_impl release]; [super dealloc]; } - (void)generate { - [_outputStream writeString: COPYRIGHT]; - [_outputStream writeString: + [_header writeString: COPYRIGHT]; + [_impl writeString: COPYRIGHT]; + + [_header writeString: + @"/* This file is automatically generated from library.xml */\n" + @"\n"]; + + [_impl writeString: @"/* This file is automatically generated from library.xml */\n" @"\n" @"#include \"config.h\"\n" + @"\n" + @"#import \"amiga-glue.h\"\n" @"\n"]; for (OFXMLElement *include in [_library elementsForName: @"include"]) - [_outputStream writeFormat: @"#import \"%@\"\n", - include.stringValue]; + [_header writeFormat: @"#import \"%@\"\n", include.stringValue]; - [_outputStream writeString: + [_header writeString: @"\n" @"#ifdef OF_AMIGAOS_M68K\n" @"# define PPC_PARAMS(...) (void)\n" @"# define M68K_ARG(type, name, reg)\t\t\\\n" @"\tregister type reg##name __asm__(#reg);\t\\\n" @@ -87,11 +97,12 @@ @"\ttype name = reg##name;\n" @"#else\n" @"# define PPC_PARAMS(...) (__VA_ARGS__)\n" @"# define M68K_ARG(...)\n" @"#endif\n" - @"\n" + @"\n"]; + [_impl writeString: @"#ifdef OF_MORPHOS\n" @"/* All __saveds functions in this file need to use the SysV " @"ABI */\n" @"__asm__ (\n" @" \".section .text\\n\"\n" @@ -113,69 +124,86 @@ size_t argumentIndex; if (returnType == nil) returnType = @"void"; - [_outputStream writeFormat: @"\n" - @"%@ __saveds\n" - @"glue_%@", - returnType, name]; - - if (arguments.count > 0) - [_outputStream writeString: @" PPC_PARAMS("]; - else - [_outputStream writeString: @"(void"]; + [_header writeFormat: + @"extern %@%@glue_%@", + returnType, + (![returnType hasSuffix: @"*"] ? @" " : @""), + name]; + + [_impl writeFormat: @"\n" + @"%@ __saveds\n" + @"glue_%@", + returnType, name]; + + if (arguments.count > 0) { + [_header writeString: @" PPC_PARAMS("]; + [_impl writeString: @" PPC_PARAMS("]; + } else { + [_header writeString: @"(void"]; + [_impl writeString: @"(void"]; + } argumentIndex = 0; for (OFXMLElement *argument in arguments) { OFString *argName = [argument attributeForName: @"name"].stringValue; OFString *argType = [argument attributeForName: @"type"].stringValue; - if (argumentIndex++ > 0) - [_outputStream writeString: @", "]; + if (argumentIndex++ > 0) { + [_header writeString: @", "]; + [_impl writeString: @", "]; + } - [_outputStream writeString: argType]; - if (![argType hasSuffix: @"*"]) - [_outputStream writeString: @" "]; - [_outputStream writeString: argName]; + [_header writeString: argType]; + [_impl writeString: argType]; + if (![argType hasSuffix: @"*"]) { + [_header writeString: @" "]; + [_impl writeString: @" "]; + } + [_header writeString: argName]; + [_impl writeString: argName]; } - [_outputStream writeString: @")\n{\n"]; + [_header writeString: @");\n"]; + + [_impl writeString: @")\n{\n"]; for (OFXMLElement *argument in arguments) { OFString *argName = [argument attributeForName: @"name"].stringValue; OFString *argType = [argument attributeForName: @"type"].stringValue; OFString *m68kReg = [argument attributeForName: @"m68k-reg"].stringValue; - [_outputStream writeFormat: @"\tM68K_ARG(%@, %@, %@)\n", - argType, argName, m68kReg]; + [_impl writeFormat: @"\tM68K_ARG(%@, %@, %@)\n", + argType, argName, m68kReg]; } if (arguments.count > 0) - [_outputStream writeString: @"\n"]; + [_impl writeString: @"\n"]; if (![returnType isEqual: @"void"]) - [_outputStream writeString: @"\treturn "]; + [_impl writeString: @"\treturn "]; else - [_outputStream writeString: @"\t"]; + [_impl writeString: @"\t"]; - [_outputStream writeFormat: @"%@(", name]; + [_impl writeFormat: @"%@(", name]; argumentIndex = 0; for (OFXMLElement *argument in arguments) { OFString *argName = [argument attributeForName: @"name"].stringValue; if (argumentIndex++ > 0) - [_outputStream writeString: @", "]; + [_impl writeString: @", "]; - [_outputStream writeString: argName]; + [_impl writeString: argName]; } - [_outputStream writeString: @");\n}\n"]; + [_impl writeString: @");\n}\n"]; } } @end