Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 17 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 39 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 60 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 70 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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]; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 84 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 85 | return self; |
| 86 | } |
| 87 | |
| 88 | - (id)initForFileType: (NSString *)filetype |
| 89 | { |
| 90 | FileSettings *defaults; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 91 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 92 | defaults = [FileSettings getDefaultsForFileType: filetype]; |
| 93 | self = [self initWithFileSettings: defaults]; |
| 94 | origsource = [defaults retain]; |
| 95 | return self; |
| 96 | } |
| 97 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 98 | - (id)initForFSDefaultFileType: (NSString *)filetype |
| 99 | { |
| 100 | int i; |
| 101 | NSString *filename; |
| 102 | NSDictionary *dict; |
| 103 | static NSDictionary *factorySettings; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 104 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 105 | self = [super init]; |
| 106 | if (!self) return self; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 107 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 146 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 147 | defaults = [NSUserDefaults standardUserDefaults]; |
| 148 | dict = [defaults dictionaryForKey: filetype]; |
| 149 | if (!dict) |
| 150 | return; |
| 151 | [self applyValuesFromDict: dict]; |
| 152 | } |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 153 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 154 | - (id)initForDefaultFileType: (NSString *)filetype |
| 155 | { |
| 156 | FileSettings *fsdefaults; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 157 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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", |
Ronald Oussoren | 3778bf5 | 2006-10-08 17:40:02 +0000 | [diff] [blame] | 204 | [NSNumber numberWithBool: tabs], @"tabs", |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 217 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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]; |
Ronald Oussoren | 3778bf5 | 2006-10-08 17:40:02 +0000 | [diff] [blame] | 232 | value = [dict objectForKey: @"tabs"]; |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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 | |
Ronald Oussoren | 26cad08 | 2006-08-01 21:00:57 +0000 | [diff] [blame] | 242 | - (NSString*)_replaceSingleQuotes: (NSString*)string |
| 243 | { |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 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:@"'"]; |
Ronald Oussoren | 26cad08 | 2006-08-01 21:00:57 +0000 | [diff] [blame] | 248 | |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 249 | return [components componentsJoinedByString:@"'\"'\"'"]; |
Ronald Oussoren | 26cad08 | 2006-08-01 21:00:57 +0000 | [diff] [blame] | 250 | } |
| 251 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 252 | - (NSString *)commandLineForScript: (NSString *)script |
| 253 | { |
| 254 | NSString *cur_interp = NULL; |
Ronald Oussoren | 26cad08 | 2006-08-01 21:00:57 +0000 | [diff] [blame] | 255 | NSString* script_dir = NULL; |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 256 | char hashbangbuf[1024]; |
| 257 | FILE *fp; |
| 258 | char *p; |
Ronald Oussoren | 26cad08 | 2006-08-01 21:00:57 +0000 | [diff] [blame] | 259 | |
| 260 | script_dir = [script substringToIndex: |
| 261 | [script length]-[[script lastPathComponent] length]]; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 262 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 263 | if (honourhashbang && |
Ronald Oussoren | 451e824 | 2009-03-30 19:22:56 +0000 | [diff] [blame] | 264 | (fp=fopen([script fileSystemRepresentation], "r")) && |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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++; |
Ronald Oussoren | 451e824 | 2009-03-30 19:22:56 +0000 | [diff] [blame] | 271 | cur_interp = [NSString stringWithUTF8String: p]; |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 272 | } |
| 273 | if (!cur_interp) |
| 274 | cur_interp = interpreter; |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 275 | |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 276 | return [NSString stringWithFormat: |
Ronald Oussoren | 26cad08 | 2006-08-01 21:00:57 +0000 | [diff] [blame] | 277 | @"cd '%@' && '%@'%s%s%s%s%s%s %@ '%@' %@ %s", |
| 278 | [self _replaceSingleQuotes:script_dir], |
| 279 | [self _replaceSingleQuotes:cur_interp], |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 280 | debug?" -d":"", |
| 281 | verbose?" -v":"", |
| 282 | inspect?" -i":"", |
| 283 | optimize?" -O":"", |
| 284 | nosite?" -S":"", |
| 285 | tabs?" -t":"", |
| 286 | others, |
Ronald Oussoren | 26cad08 | 2006-08-01 21:00:57 +0000 | [diff] [blame] | 287 | [self _replaceSingleQuotes:script], |
Ronald Oussoren | 3778bf5 | 2006-10-08 17:40:02 +0000 | [diff] [blame] | 288 | scriptargs ? scriptargs : @"", |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 289 | with_terminal? "&& echo Exit status: $? && exit 1" : " &"]; |
| 290 | } |
| 291 | |
| 292 | - (NSArray *) interpreters { return interpreters;}; |
| 293 | |
Ronald Oussoren | cc879a0 | 2013-07-07 09:49:23 +0200 | [diff] [blame] | 294 | // FileSettingsSource protocol |
Ronald Oussoren | c629be8 | 2006-06-07 18:58:01 +0000 | [diff] [blame] | 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 |