diff --git a/GNUmakefile b/GNUmakefile index 558a5dc..d2df18f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -11,7 +11,8 @@ include $(GNUSTEP_MAKEFILES)/common.make GNUSTEP_USE_PARALLEL_AGGREGATE=no #DBusKit Framework -SUBPROJECTS = Source +SUBPROJECTS = Source \ + Tools # # Makefiles diff --git a/Source/DKInterface.m b/Source/DKInterface.m index bbff2c4..5685dea 100644 --- a/Source/DKInterface.m +++ b/Source/DKInterface.m @@ -235,7 +235,7 @@ [declaration appendFormat: @"%@\n\n", [method methodDeclaration]]; } - [declaration appendFormat: @"@end"]; + [declaration appendFormat: @"@end\n"]; return declaration; } diff --git a/Tools/GNUmakefile b/Tools/GNUmakefile new file mode 100644 index 0000000..858a563 --- /dev/null +++ b/Tools/GNUmakefile @@ -0,0 +1,24 @@ +# +# GNUmakefile for DBusKit tools +# + +include $(GNUSTEP_MAKEFILES)/common.make + +# config.make will be generated at configure time +-include ../config.make + +GNUSTEP_USE_PARALLEL_AGGREGATE=yes + +TOOL_NAME = dk_make_protocol + +dk_make_protocol_OBJC_FILES=dk_make_protocol.m + +ADDITIONAL_LIB_DIRS += -L../Source/DBusKit.framework/Versions/Current/$(GNUSTEP_TARGET_LDIR) +ADDITIONAL_TOOL_LIBS = -lgnustep-base -lDBusKit + +# +# Makefiles +# +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/tool.make +-include GNUmakefile.postamble diff --git a/Tools/dk_make_protocol.m b/Tools/dk_make_protocol.m new file mode 100644 index 0000000..025b1f2 --- /dev/null +++ b/Tools/dk_make_protocol.m @@ -0,0 +1,189 @@ +#import +#import "../Source/DKProxy+Private.h" +#import "../Source/DKIntrospectionParserDelegate.h" +#import "../Source/DKInterface.h" + +#include +@interface DKIntrospector: NSObject +{ + NSMutableArray *nodes; + NSMutableDictionary *interfaces; +} +@end + +@implementation DKIntrospector +- (id)init +{ + if (nil == (self = [super init])) + { + return nil; + } + interfaces = [NSMutableDictionary new]; + nodes = [NSMutableArray new]; + return self; +} +- (NSString*)_path +{ + return @"/"; +} + +- (void)_addChildNode: (DKObjectPathNode*)node +{ + if (nil != node) + { + [nodes addObject: node]; + } +} + +- (void)_addInterface: (DKInterface*)interface +{ + NSString *name = [interface name]; + if (nil != name) + { + [interfaces setObject: interface + forKey: name]; + } +} + +- (NSDictionary*)_interfaces +{ + return interfaces; +} + +- (void)dealloc +{ + [interfaces release]; + [nodes release]; + [super dealloc]; +} +@end +enum +{ + EXPECT_SWITCH, + EXPECT_PATH +}; + +int main (int argc, char **argv, char **env) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSProcessInfo *info = [NSProcessInfo processInfo]; + NSArray *args = [info arguments]; + NSUInteger argCount = [args count]; + NSUInteger argIndex = 1; + NSUInteger argState = EXPECT_SWITCH; + BOOL useObjC2 = NO; + NSString *inPath = nil; + NSString *outPath = nil; + NSString **pathAddr = NULL; + NSURL *inURL = nil; + NSXMLParser *parser = nil; + DKIntrospectionParserDelegate *delegate = nil; + DKIntrospector *spector = nil; + NSFileHandle *outHandle = nil; + NSDictionary *interfaces = nil; + DKInterface *thisIf = nil; + NSEnumerator *ifEnum = nil; + + if (argCount == 1) + { + GSPrintf(stderr, @"Usage: Use '-i' to specify the input file and '-o' to specify the output file.\nIf no output file is given, stdout is used.\n"); + return 1; + } + for (argIndex = 1; argIndex < argCount; argIndex++) + { + NSString *thisArg = [args objectAtIndex: argIndex]; + if (([thisArg hasPrefix: @"-"]) && (EXPECT_SWITCH == argState)) + { + if ([thisArg isEqualToString: @"-2"]) + { + useObjC2 = YES; + argState = EXPECT_SWITCH; + } + else if ([thisArg isEqualToString: @"-i"]) + { + pathAddr = &inPath; + argState = EXPECT_PATH; + } + else if ([thisArg isEqualToString: @"-o"]) + { + pathAddr = &outPath; + argState = EXPECT_PATH; + } + } + else if (EXPECT_PATH == argState) + { + if (pathAddr != NULL) + { + *pathAddr = thisArg; + } + argState = EXPECT_SWITCH; + } + else + { + pathAddr = NULL; + } + } + + if (nil == inPath) + { + return 1; + } + + inURL = [NSURL fileURLWithPath: [inPath stringByStandardizingPath]]; + if (nil == inURL) + { + return 1; + } + + spector = [[[DKIntrospector alloc] init] autorelease]; + + delegate = [[[DKIntrospectionParserDelegate alloc] initWithParentForNodes: spector] autorelease]; + + parser = [[[NSXMLParser alloc] initWithContentsOfURL: inURL] autorelease]; + [parser setDelegate: delegate]; + [parser parse]; + + interfaces = [spector _interfaces]; + if (0 == [interfaces count]) + { + GSPrintf(stderr, @"No interfaces found.\n"); + return 1; + } + + if (outPath == nil) + { + outHandle = [NSFileHandle fileHandleWithStandardOutput]; + } + else + { + int fd = -1; + outPath = [outPath stringByStandardizingPath]; + fd = creat([outPath UTF8String], 0644); + if (-1 == fd) + { + GSPrintf(stderr,@"Could not open '%@'.\n", outPath); + return 1; + } + outHandle = [[[NSFileHandle alloc] initWithFileDescriptor: fd + closeOnDealloc: NO] autorelease]; + } + if (outHandle == nil) + { + GSPrintf(stderr, @"Could write data.\n"); + return 1; + } + + ifEnum = [interfaces objectEnumerator]; + while (nil != (thisIf = [ifEnum nextObject])) + { + NSString *preamble = [NSString stringWithFormat: @"#import \n\n/*\n * Objective-C protocol declaration for the D-Bus %@ interface.\n */\n", + [thisIf name]]; + [outHandle writeData: [preamble dataUsingEncoding: NSUTF8StringEncoding + allowLossyConversion: YES]]; + [outHandle writeData: [[thisIf protocolDeclaration] dataUsingEncoding: NSUTF8StringEncoding + allowLossyConversion: YES]]; + } + [outHandle closeFile]; + [pool release]; + return 0; +}