diff --git a/ddcli/DDGetoptLongParser.h b/ddcli/DDGetoptLongParser.h index d61e4074..a0c09a6e 100644 --- a/ddcli/DDGetoptLongParser.h +++ b/ddcli/DDGetoptLongParser.h @@ -42,6 +42,8 @@ typedef enum DDGetoptArgumentOptions DDGetoptOptionalArgument = optional_argument, /** Option takes a mandatory argument */ DDGetoptRequiredArgument = required_argument, + /** Option takes a key-value pair argument */ + DDGetoptKeyValueArgument, } DDGetoptArgumentOptions; /** diff --git a/ddcli/DDGetoptLongParser.m b/ddcli/DDGetoptLongParser.m index a383def1..de3962bc 100644 --- a/ddcli/DDGetoptLongParser.m +++ b/ddcli/DDGetoptLongParser.m @@ -120,7 +120,7 @@ - (void) addLongOption: (NSString *) longOption struct option * option = [self currentOption]; option->name = utf8String; - option->has_arg = argumentOptions; + option->has_arg = argumentOptions == DDGetoptKeyValueArgument ? DDGetoptRequiredArgument : argumentOptions; option->flag = NULL; int shortOptionValue; @@ -128,7 +128,7 @@ - (void) addLongOption: (NSString *) longOption { shortOptionValue = shortOption; option->val = shortOption; - if (argumentOptions == DDGetoptRequiredArgument) + if (argumentOptions == DDGetoptRequiredArgument || argumentOptions == DDGetoptKeyValueArgument) [mOptionString appendFormat: @"%c:", shortOption]; else if (argumentOptions == DDGetoptOptionalArgument) [mOptionString appendFormat: @"%c::", shortOption]; @@ -220,6 +220,36 @@ - (NSArray *) parseOptionsWithArguments: (NSArray *) arguments int argumentOptions = [[optionInfo objectAtIndex: 1] intValue]; if (argumentOptions == DDGetoptNoArgument) [mTarget setValue: [NSNumber numberWithBool: YES] forKey: key]; + else if (argumentOptions == DDGetoptKeyValueArgument) + { + // Split the arguement on the '=' sign + NSArray *pair = [nsoptarg componentsSeparatedByString:@"="]; + // Build a keypath from the argument and the new key + NSString *keypath = [NSString stringWithFormat:@"%@.%@", key, [pair objectAtIndex:0]]; + + // If it is a number or a boolean, we'll parse that out + NSString *value = [pair objectAtIndex:1]; + id parsedValue = value; + // Looks like a boolean? + if ([value isCaseInsensitiveLike:@"true"] || [value isCaseInsensitiveLike:@"false"]) + { + parsedValue = [NSNumber numberWithBool:[value boolValue]]; + } + else + { + // Looks like a number? + NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; + [formatter setAllowsFloats:YES]; + NSNumber *numberValue = [formatter numberFromString:value]; + if (numberValue) + { + parsedValue = numberValue; + } + [formatter release]; + } + + [mTarget setValue:parsedValue forKeyPath:keypath]; + } else [mTarget setValue: nsoptarg forKey: key]; } diff --git a/mogenerator.h b/mogenerator.h index 0cf4da60..06046a3a 100644 --- a/mogenerator.h +++ b/mogenerator.h @@ -56,6 +56,7 @@ BOOL _version; BOOL _listSourceFiles; BOOL _orphaned; + NSMutableDictionary *templateVar; } - (NSString*)appSupportFileNamed:(NSString*)fileName_; diff --git a/mogenerator.m b/mogenerator.m index 2dff83a8..379e41fc 100644 --- a/mogenerator.m +++ b/mogenerator.m @@ -8,6 +8,7 @@ #import "mogenerator.h" #import "RegexKitLite.h" +static NSString *kTemplateVar = @"TemplateVar"; NSString *gCustomBaseClass; @interface NSEntityDescription (fetchedPropertiesAdditions) @@ -284,6 +285,19 @@ - (NSString*)camelCaseString { @implementation MOGeneratorApp +- (id)init { + self = [super init]; + if (self) { + templateVar = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (void)dealloc { + [templateVar release]; + [super dealloc]; +} + NSString *ApplicationSupportSubdirectoryName = @"mogenerator"; - (NSString*)appSupportFileNamed:(NSString*)fileName_ { NSFileManager *fileManager = [NSFileManager defaultManager]; @@ -343,6 +357,7 @@ - (void) application: (DDCliApplication *) app {@"help", 'h', DDGetoptNoArgument}, {@"version", 0, DDGetoptNoArgument}, + {@"template-var", 0, DDGetoptKeyValueArgument}, {nil, 0, 0}, }; [optionsParser addOptionsFromTable: optionTable]; @@ -358,6 +373,7 @@ - (void) printUsage; " --includeh FILE Generate aggregate include file for .h files for human generated source files only\n" " --template-path PATH Path to templates (absolute or relative to model path)\n" " --template-group NAME Name of template group\n" + " --template-var KEY=VALUE A key-value pair to pass to the template file. There can be many of these.\n" " -O, --output-dir DIR Output directory\n" " -M, --machine-dir DIR Output directory for machine files\n" " -H, --human-dir DIR Output directory for human files\n" @@ -582,6 +598,12 @@ - (int) application: (DDCliApplication *) app MiscMergeEngine *humanM = engineWithTemplatePath([self appSupportFileNamed:@"human.m.motemplate"]); assert(humanM); + // Add the template var dictionary to each of the merge engines + [machineH setEngineValue:templateVar forKey:kTemplateVar]; + [machineM setEngineValue:templateVar forKey:kTemplateVar]; + [humanH setEngineValue:templateVar forKey:kTemplateVar]; + [humanM setEngineValue:templateVar forKey:kTemplateVar]; + NSMutableArray *humanMFiles = [NSMutableArray array], *humanHFiles = [NSMutableArray array], *machineMFiles = [NSMutableArray array], diff --git a/templates/machine.h.motemplate b/templates/machine.h.motemplate index b3d55db2..779ad084 100644 --- a/templates/machine.h.motemplate +++ b/templates/machine.h.motemplate @@ -19,7 +19,11 @@ <$foreach Attribute noninheritedAttributes do$> <$if Attribute.hasDefinedAttributeType$> +<$if TemplateVar.arc$> +@property (nonatomic, strong) <$Attribute.objectAttributeType$> *<$Attribute.name$>; +<$else$> @property (nonatomic, retain) <$Attribute.objectAttributeType$> *<$Attribute.name$>; +<$endif$> <$if Attribute.hasScalarAttributeType$> @property <$Attribute.scalarAttributeType$> <$Attribute.name$>Value; - (<$Attribute.scalarAttributeType$>)<$Attribute.name$>Value; @@ -30,10 +34,18 @@ <$endforeach do$> <$foreach Relationship noninheritedRelationships do$> <$if Relationship.isToMany$> +<$if TemplateVar.arc$> +@property (nonatomic, strong) NSSet* <$Relationship.name$>; +<$else$> @property (nonatomic, retain) NSSet* <$Relationship.name$>; +<$endif$> - (NSMutableSet*)<$Relationship.name$>Set; <$else$> +<$if TemplateVar.arc$> +@property (nonatomic, strong) <$Relationship.destinationEntity.managedObjectClassName$>* <$Relationship.name$>; +<$else$> @property (nonatomic, retain) <$Relationship.destinationEntity.managedObjectClassName$>* <$Relationship.name$>; +<$endif$> //- (BOOL)validate<$Relationship.name.initialCapitalString$>:(id*)value_ error:(NSError**)error_; <$endif$> <$endforeach do$>