Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Mac/PythonLauncher/FileSettings.m
12 views
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
309