5 // Created by Jack Jansen on Sun Jul 21 2002.
6 // Copyright (c) 2002 __MyCompanyName__. All rights reserved.
9 #import "FileSettings.h"
11 @implementation FileSettings
13 + (id)getFactorySettingsForFileType: (NSString *)filetype
15 static FileSettings *fsdefault_py, *fsdefault_pyw, *fsdefault_pyc;
16 FileSettings **curdefault;
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;
25 NSLog(@"Funny File Type: %@\n", filetype);
26 curdefault = &fsdefault_py;
27 filetype = @"Python Script";
30 *curdefault = [[FileSettings new] initForFSDefaultFileType: filetype];
35 + (id)getDefaultsForFileType: (NSString *)filetype
37 static FileSettings *default_py, *default_pyw, *default_pyc;
38 FileSettings **curdefault;
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;
47 NSLog(@"Funny File Type: %@\n", filetype);
48 curdefault = &default_py;
49 filetype = @"Python Script";
52 *curdefault = [[FileSettings new] initForDefaultFileType: filetype];
57 + (id)newSettingsForFileType: (NSString *)filetype
61 cur = [FileSettings new];
62 [cur initForFileType: filetype];
66 - (id)initWithFileSettings: (FileSettings *)source
69 if (!self) return self;
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;
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];
88 - (id)initForFileType: (NSString *)filetype
90 FileSettings *defaults;
92 defaults = [FileSettings getDefaultsForFileType: filetype];
93 self = [self initWithFileSettings: defaults];
94 origsource = [defaults retain];
100 // self = [self initForFileType: @"Python Script"];
104 - (id)initForFSDefaultFileType: (NSString *)filetype
109 static NSDictionary *factorySettings;
112 if (!self) return self;
114 if (factorySettings == NULL) {
115 NSBundle *bdl = [NSBundle mainBundle];
116 NSString *path = [ bdl pathForResource: @"factorySettings"
118 factorySettings = [[NSDictionary dictionaryWithContentsOfFile:
120 if (factorySettings == NULL) {
121 NSLog(@"Missing %@", path);
125 dict = [factorySettings objectForKey: filetype];
127 NSLog(@"factorySettings.plist misses file type \"%@\"", filetype);
128 interpreter = [@"no default found" retain];
131 [self applyValuesFromDict: dict];
132 interpreters = [dict objectForKey: @"interpreter_list"];
134 for (i=0; i < [interpreters count]; i++) {
135 filename = [interpreters objectAtIndex: i];
136 filename = [filename stringByExpandingTildeInPath];
137 if ([[NSFileManager defaultManager] fileExistsAtPath: filename]) {
138 interpreter = [filename retain];
142 if (interpreter == NULL)
143 interpreter = [@"no default found" retain];
148 - (void)applyUserDefaults: (NSString *)filetype
150 NSUserDefaults *defaults;
153 defaults = [NSUserDefaults standardUserDefaults];
154 dict = [defaults dictionaryForKey: filetype];
157 [self applyValuesFromDict: dict];
160 - (id)initForDefaultFileType: (NSString *)filetype
162 FileSettings *fsdefaults;
164 fsdefaults = [FileSettings getFactorySettingsForFileType: filetype];
165 self = [self initWithFileSettings: fsdefaults];
166 if (!self) return self;
167 interpreters = [fsdefaults->interpreters retain];
168 scriptargs = [@"" retain];
169 [self applyUserDefaults: filetype];
170 prefskey = [filetype retain];
177 [self updateFromSource: origsource];
179 FileSettings *fsdefaults;
180 fsdefaults = [FileSettings getFactorySettingsForFileType: prefskey];
181 [self updateFromSource: fsdefaults];
185 - (void)updateFromSource: (id <FileSettingsSource>)source
187 interpreter = [[source interpreter] retain];
188 honourhashbang = [source honourhashbang];
189 debug = [source debug];
190 verbose = [source verbose];
191 inspect = [source inspect];
192 optimize = [source optimize];
193 nosite = [source nosite];
194 tabs = [source tabs];
195 others = [[source others] retain];
196 scriptargs = [[source scriptargs] retain];
197 with_terminal = [source with_terminal];
198 // And if this is a user defaults object we also save the
201 NSUserDefaults *defaults;
202 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
203 interpreter, @"interpreter",
204 [NSNumber numberWithBool: honourhashbang], @"honourhashbang",
205 [NSNumber numberWithBool: debug], @"debug",
206 [NSNumber numberWithBool: verbose], @"verbose",
207 [NSNumber numberWithBool: inspect], @"inspect",
208 [NSNumber numberWithBool: optimize], @"optimize",
209 [NSNumber numberWithBool: nosite], @"nosite",
210 [NSNumber numberWithBool: tabs], @"tabs",
212 scriptargs, @"scriptargs",
213 [NSNumber numberWithBool: with_terminal], @"with_terminal",
215 defaults = [NSUserDefaults standardUserDefaults];
216 [defaults setObject: dict forKey: prefskey];
220 - (void)applyValuesFromDict: (NSDictionary *)dict
224 value = [dict objectForKey: @"interpreter"];
225 if (value) interpreter = [value retain];
226 value = [dict objectForKey: @"honourhashbang"];
227 if (value) honourhashbang = [value boolValue];
228 value = [dict objectForKey: @"debug"];
229 if (value) debug = [value boolValue];
230 value = [dict objectForKey: @"verbose"];
231 if (value) verbose = [value boolValue];
232 value = [dict objectForKey: @"inspect"];
233 if (value) inspect = [value boolValue];
234 value = [dict objectForKey: @"optimize"];
235 if (value) optimize = [value boolValue];
236 value = [dict objectForKey: @"nosite"];
237 if (value) nosite = [value boolValue];
238 value = [dict objectForKey: @"tabs"];
239 if (value) tabs = [value boolValue];
240 value = [dict objectForKey: @"others"];
241 if (value) others = [value retain];
242 value = [dict objectForKey: @"scriptargs"];
243 if (value) scriptargs = [value retain];
244 value = [dict objectForKey: @"with_terminal"];
245 if (value) with_terminal = [value boolValue];
248 - (NSString*)_replaceSingleQuotes: (NSString*)string
250 /* Replace all single-quotes by '"'"', that way shellquoting will
251 * be correct when the result value is delimited using single quotes.
253 NSArray* components = [string componentsSeparatedByString:@"'"];
255 return [components componentsJoinedByString:@"'\"'\"'"];
258 - (NSString *)commandLineForScript: (NSString *)script
260 NSString *cur_interp = NULL;
261 NSString* script_dir = NULL;
262 char hashbangbuf[1024];
266 script_dir = [script substringToIndex:
267 [script length]-[[script lastPathComponent] length]];
269 if (honourhashbang &&
270 (fp=fopen([script fileSystemRepresentation], "r")) &&
271 fgets(hashbangbuf, sizeof(hashbangbuf), fp) &&
272 strncmp(hashbangbuf, "#!", 2) == 0 &&
273 (p=strchr(hashbangbuf, '\n'))) {
276 while (*p == ' ') p++;
277 cur_interp = [NSString stringWithUTF8String: p];
280 cur_interp = interpreter;
282 return [NSString stringWithFormat:
283 @"cd '%@' && '%@'%s%s%s%s%s%s %@ '%@' %@ %s",
284 [self _replaceSingleQuotes:script_dir],
285 [self _replaceSingleQuotes:cur_interp],
293 [self _replaceSingleQuotes:script],
294 scriptargs ? scriptargs : @"",
295 with_terminal? "&& echo Exit status: $? && exit 1" : " &"];
298 - (NSArray *) interpreters { return interpreters;};
300 // FileSettingsSource protocol
301 - (NSString *) interpreter { return interpreter;};
302 - (BOOL) honourhashbang { return honourhashbang; };
303 - (BOOL) debug { return debug;};
304 - (BOOL) verbose { return verbose;};
305 - (BOOL) inspect { return inspect;};
306 - (BOOL) optimize { return optimize;};
307 - (BOOL) nosite { return nosite;};
308 - (BOOL) tabs { return tabs;};
309 - (NSString *) others { return others;};
310 - (NSString *) scriptargs { return scriptargs;};
311 - (BOOL) with_terminal { return with_terminal;};