1// 2// FileSettings.m 3// PythonLauncher 4// 5// Created by Jack Jansen on Sun Jul 21 2002. 6// Copyright (c) 2002 __MyCompanyName__. All rights reserved. 7// 8 9#import "FileSettings.h" 10 11@implementation FileSettings 12 13+ (id)getFactorySettingsForFileType: (NSString *)filetype 14{ 15 static FileSettings *fsdefault_py, *fsdefault_pyw, *fsdefault_pyc; 16 FileSettings **curdefault; 17 18 if ([filetype isEqualToString: @"Python Script"]) { 19 curdefault = &fsdefault_py; 20 } else if ([filetype isEqualToString: @"Python GUI Script"]) { 21 curdefault = &fsdefault_pyw; 22 } else if ([filetype isEqualToString: @"Python Bytecode Document"]) { 23 curdefault = &fsdefault_pyc; 24 } else { 25 NSLog(@"Funny File Type: %@\n", filetype); 26 curdefault = &fsdefault_py; 27 filetype = @"Python Script"; 28 } 29 if (!*curdefault) { 30 *curdefault = [[FileSettings new] initForFSDefaultFileType: filetype]; 31 } 32 return *curdefault; 33} 34 35+ (id)getDefaultsForFileType: (NSString *)filetype 36{ 37 static FileSettings *default_py, *default_pyw, *default_pyc; 38 FileSettings **curdefault; 39 40 if ([filetype isEqualToString: @"Python Script"]) { 41 curdefault = &default_py; 42 } else if ([filetype isEqualToString: @"Python GUI Script"]) { 43 curdefault = &default_pyw; 44 } else if ([filetype isEqualToString: @"Python Bytecode Document"]) { 45 curdefault = &default_pyc; 46 } else { 47 NSLog(@"Funny File Type: %@\n", filetype); 48 curdefault = &default_py; 49 filetype = @"Python Script"; 50 } 51 if (!*curdefault) { 52 *curdefault = [[FileSettings new] initForDefaultFileType: filetype]; 53 } 54 return *curdefault; 55} 56 57+ (id)newSettingsForFileType: (NSString *)filetype 58{ 59 FileSettings *cur; 60 61 cur = [FileSettings new]; 62 [cur initForFileType: filetype]; 63 return [cur retain]; 64} 65 66- (id)initWithFileSettings: (FileSettings *)source 67{ 68 self = [super init]; 69 if (!self) return self; 70 71 interpreter = [source->interpreter retain]; 72 honourhashbang = source->honourhashbang; 73 debug = source->debug; 74 verbose = source->verbose; 75 inspect = source->inspect; 76 optimize = source->optimize; 77 nosite = source->nosite; 78 tabs = source->tabs; 79 others = [source->others retain]; 80 scriptargs = [source->scriptargs retain]; 81 with_terminal = source->with_terminal; 82 prefskey = source->prefskey; 83 if (prefskey) [prefskey retain]; 84 85 return self; 86} 87 88- (id)initForFileType: (NSString *)filetype 89{ 90 FileSettings *defaults; 91 92 defaults = [FileSettings getDefaultsForFileType: filetype]; 93 self = [self initWithFileSettings: defaults]; 94 origsource = [defaults retain]; 95 return self; 96} 97 98- (id)initForFSDefaultFileType: (NSString *)filetype 99{ 100 int i; 101 NSString *filename; 102 NSDictionary *dict; 103 static NSDictionary *factorySettings; 104 105 self = [super init]; 106 if (!self) return self; 107 108 if (factorySettings == NULL) { 109 NSBundle *bdl = [NSBundle mainBundle]; 110 NSString *path = [ bdl pathForResource: @"factorySettings" 111 ofType: @"plist"]; 112 factorySettings = [[NSDictionary dictionaryWithContentsOfFile: 113 path] retain]; 114 if (factorySettings == NULL) { 115 NSLog(@"Missing %@", path); 116 return NULL; 117 } 118 } 119 dict = [factorySettings objectForKey: filetype]; 120 if (dict == NULL) { 121 NSLog(@"factorySettings.plist misses file type \"%@\"", filetype); 122 interpreter = [@"no default found" retain]; 123 return NULL; 124 } 125 [self applyValuesFromDict: dict]; 126 interpreters = [dict objectForKey: @"interpreter_list"]; 127 interpreter = NULL; 128 for (i=0; i < [interpreters count]; i++) { 129 filename = [interpreters objectAtIndex: i]; 130 filename = [filename stringByExpandingTildeInPath]; 131 if ([[NSFileManager defaultManager] fileExistsAtPath: filename]) { 132 interpreter = [filename retain]; 133 break; 134 } 135 } 136 if (interpreter == NULL) 137 interpreter = [@"no default found" retain]; 138 origsource = NULL; 139 return self; 140} 141 142- (void)applyUserDefaults: (NSString *)filetype 143{ 144 NSUserDefaults *defaults; 145 NSDictionary *dict; 146 147 defaults = [NSUserDefaults standardUserDefaults]; 148 dict = [defaults dictionaryForKey: filetype]; 149 if (!dict) 150 return; 151 [self applyValuesFromDict: dict]; 152} 153 154- (id)initForDefaultFileType: (NSString *)filetype 155{ 156 FileSettings *fsdefaults; 157 158 fsdefaults = [FileSettings getFactorySettingsForFileType: filetype]; 159 self = [self initWithFileSettings: fsdefaults]; 160 if (!self) return self; 161 interpreters = [fsdefaults->interpreters retain]; 162 scriptargs = [@"" retain]; 163 [self applyUserDefaults: filetype]; 164 prefskey = [filetype retain]; 165 return self; 166} 167 168- (void)reset 169{ 170 if (origsource) { 171 [self updateFromSource: origsource]; 172 } else { 173 FileSettings *fsdefaults; 174 fsdefaults = [FileSettings getFactorySettingsForFileType: prefskey]; 175 [self updateFromSource: fsdefaults]; 176 } 177} 178 179- (void)updateFromSource: (id <FileSettingsSource>)source 180{ 181 interpreter = [[source interpreter] retain]; 182 honourhashbang = [source honourhashbang]; 183 debug = [source debug]; 184 verbose = [source verbose]; 185 inspect = [source inspect]; 186 optimize = [source optimize]; 187 nosite = [source nosite]; 188 tabs = [source tabs]; 189 others = [[source others] retain]; 190 scriptargs = [[source scriptargs] retain]; 191 with_terminal = [source with_terminal]; 192 // And if this is a user defaults object we also save the 193 // values 194 if (!origsource) { 195 NSUserDefaults *defaults; 196 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: 197 interpreter, @"interpreter", 198 [NSNumber numberWithBool: honourhashbang], @"honourhashbang", 199 [NSNumber numberWithBool: debug], @"debug", 200 [NSNumber numberWithBool: verbose], @"verbose", 201 [NSNumber numberWithBool: inspect], @"inspect", 202 [NSNumber numberWithBool: optimize], @"optimize", 203 [NSNumber numberWithBool: nosite], @"nosite", 204 [NSNumber numberWithBool: tabs], @"tabs", 205 others, @"others", 206 scriptargs, @"scriptargs", 207 [NSNumber numberWithBool: with_terminal], @"with_terminal", 208 nil]; 209 defaults = [NSUserDefaults standardUserDefaults]; 210 [defaults setObject: dict forKey: prefskey]; 211 } 212} 213 214- (void)applyValuesFromDict: (NSDictionary *)dict 215{ 216 id value; 217 218 value = [dict objectForKey: @"interpreter"]; 219 if (value) interpreter = [value retain]; 220 value = [dict objectForKey: @"honourhashbang"]; 221 if (value) honourhashbang = [value boolValue]; 222 value = [dict objectForKey: @"debug"]; 223 if (value) debug = [value boolValue]; 224 value = [dict objectForKey: @"verbose"]; 225 if (value) verbose = [value boolValue]; 226 value = [dict objectForKey: @"inspect"]; 227 if (value) inspect = [value boolValue]; 228 value = [dict objectForKey: @"optimize"]; 229 if (value) optimize = [value boolValue]; 230 value = [dict objectForKey: @"nosite"]; 231 if (value) nosite = [value boolValue]; 232 value = [dict objectForKey: @"tabs"]; 233 if (value) tabs = [value boolValue]; 234 value = [dict objectForKey: @"others"]; 235 if (value) others = [value retain]; 236 value = [dict objectForKey: @"scriptargs"]; 237 if (value) scriptargs = [value retain]; 238 value = [dict objectForKey: @"with_terminal"]; 239 if (value) with_terminal = [value boolValue]; 240} 241 242- (NSString*)_replaceSingleQuotes: (NSString*)string 243{ 244 /* Replace all single-quotes by '"'"', that way shellquoting will 245 * be correct when the result value is delimited using single quotes. 246 */ 247 NSArray* components = [string componentsSeparatedByString:@"'"]; 248 249 return [components componentsJoinedByString:@"'\"'\"'"]; 250} 251 252- (NSString *)commandLineForScript: (NSString *)script 253{ 254 NSString *cur_interp = NULL; 255 NSString* script_dir = NULL; 256 char hashbangbuf[1024]; 257 FILE *fp; 258 char *p; 259 260 script_dir = [script substringToIndex: 261 [script length]-[[script lastPathComponent] length]]; 262 263 if (honourhashbang && 264 (fp=fopen([script fileSystemRepresentation], "r")) && 265 fgets(hashbangbuf, sizeof(hashbangbuf), fp) && 266 strncmp(hashbangbuf, "#!", 2) == 0 && 267 (p=strchr(hashbangbuf, '\n'))) { 268 *p = '\0'; 269 p = hashbangbuf + 2; 270 while (*p == ' ') p++; 271 cur_interp = [NSString stringWithUTF8String: p]; 272 } 273 if (!cur_interp) 274 cur_interp = interpreter; 275 276 return [NSString stringWithFormat: 277 @"cd '%@' && '%@'%s%s%s%s%s%s %@ '%@' %@ %s", 278 [self _replaceSingleQuotes:script_dir], 279 [self _replaceSingleQuotes:cur_interp], 280 debug?" -d":"", 281 verbose?" -v":"", 282 inspect?" -i":"", 283 optimize?" -O":"", 284 nosite?" -S":"", 285 tabs?" -t":"", 286 others, 287 [self _replaceSingleQuotes:script], 288 scriptargs ? scriptargs : @"", 289 with_terminal? "&& echo Exit status: $? && exit 1" : " &"]; 290} 291 292- (NSArray *) interpreters { return interpreters;}; 293 294// FileSettingsSource protocol 295- (NSString *) interpreter { return interpreter;}; 296- (BOOL) honourhashbang { return honourhashbang; }; 297- (BOOL) debug { return debug;}; 298- (BOOL) verbose { return verbose;}; 299- (BOOL) inspect { return inspect;}; 300- (BOOL) optimize { return optimize;}; 301- (BOOL) nosite { return nosite;}; 302- (BOOL) tabs { return tabs;}; 303- (NSString *) others { return others;}; 304- (NSString *) scriptargs { return scriptargs;}; 305- (BOOL) with_terminal { return with_terminal;}; 306 307@end 308