-
Notifications
You must be signed in to change notification settings - Fork 68
/
PLKExecutive.m
135 lines (114 loc) · 4.86 KB
/
PLKExecutive.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#import "PLKExecutive.h"
#import "PLKClojureScriptEngine.h"
#import "PLKRepl.h"
#import "PLKScript.h"
#import "PLKUtils.h"
@interface PLKExecutive()
@property (strong, nonatomic) PLKClojureScriptEngine* clojureScriptEngine;
@end
@implementation PLKExecutive
-(int)runScripts:(NSArray*)scripts
srcPaths:(NSArray*)srcPaths
verbose:(BOOL)verbose
mainNsName:(NSString*)mainNsName
repl:(BOOL)repl
outPath:(NSString*)outPath
cachePath:(NSString*)cachePath
dumbTerminal:(BOOL)dumbTerminal
staticFns:(BOOL)staticFns
args:(NSArray*)args
planckVersion:(NSString*)planckVersion {
int exitValue = EXIT_SUCCESS;
NSArray* boundArgs = args;
if (!repl && !mainNsName && args.count > 0) {
// the first arg will be treated as a path to a file to be executed and should not be bound
boundArgs = [args subarrayWithRange:NSMakeRange(1, args.count - 1)];
}
[self setupClojureScriptEngineWithSrcPaths:srcPaths outPath:outPath cachePath:cachePath verbose:verbose staticFns:staticFns boundArgs:boundArgs planckVersion:planckVersion];
// Process init arguments
for (PLKScript *script in scripts) {
exitValue = [self executeScript:script];
if (exitValue != EXIT_SUCCESS) {
return exitValue;
}
}
// Process main arguments
if (mainNsName) {
exitValue = [self.clojureScriptEngine runMainInNs:mainNsName args:args];
} else if (!repl && args.count > 0) {
PLKScript *script;
// We treat the first arg as a path to a file to be executed (it can be '-', which means stdin)
NSString *path = args[0];
if ([path isEqualToString:@"-"]) {
script = [[PLKScript alloc] initWithStdIn];
} else {
script = [[PLKScript alloc] initWithPath:[self fullyQualify:path]];
}
exitValue = [self executeScript:script];
} else if (repl) {
exitValue = [[[PLKRepl alloc] init] runUsingClojureScriptEngine:self.clojureScriptEngine dumbTerminal:dumbTerminal];
}
[self.clojureScriptEngine awaitShutdown];
return exitValue;
}
-(void)setupClojureScriptEngineWithSrcPaths:(NSArray*)srcPaths outPath:(NSString*)outPath cachePath:(NSString*)cachePath verbose:(BOOL)verbose staticFns:(BOOL)staticFns boundArgs:(NSArray*)boundArgs planckVersion:(NSString*)planckVersion
{
NSMutableArray* adjustedSrcPaths = [[NSMutableArray alloc] init];
for (NSArray* srcPath in srcPaths) {
NSString* type = srcPath[0];
NSString* path = srcPath[1];
path = [self fullyQualify:path];
if ([type isEqualToString:@"src"]) {
path = [self ensureTrailingSlash:path];
}
if ([type isEqualToString:@"jar"] && [path hasSuffix:@"*"]) {
NSArray *dirFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[path substringToIndex:path.length - 1] error:nil];
NSArray *jarFiles = [dirFiles filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.jar'"]];
for (NSString* jarFile in jarFiles) {
[adjustedSrcPaths addObject:@[type, jarFile]];
}
} else {
[adjustedSrcPaths addObject:@[type, path]];
}
}
if (verbose) {
fprintf(stderr, "Classpath resolves to:\n");
for (NSArray* srcPath in adjustedSrcPaths) {
NSString* type = srcPath[0];
NSString* location = srcPath[1];
fprintf(stderr, "type: %s, location: %s\n",
[type cStringUsingEncoding:NSUTF8StringEncoding],
[location cStringUsingEncoding:NSUTF8StringEncoding]);
}
}
outPath = [self ensureTrailingSlash:[self fullyQualify:outPath]];
self.clojureScriptEngine = [[PLKClojureScriptEngine alloc] init];
[self.clojureScriptEngine startInitializationWithSrcPaths:adjustedSrcPaths outPath:outPath cachePath:cachePath verbose:verbose staticFns:staticFns boundArgs:boundArgs planckVersion:planckVersion];
}
-(NSString*)ensureTrailingSlash:(NSString*)s
{
if (!s) {
return nil;
}
if ([s hasSuffix:@"/"]) {
return s;
}
return [s stringByAppendingString:@"/"];
}
-(NSString*)fullyQualify:(NSString*)path
{
NSString* currentDirectory = [self ensureTrailingSlash:[NSFileManager defaultManager].currentDirectoryPath];
if (path && ![path hasPrefix:@"/"]) {
path = [currentDirectory stringByAppendingString:path];
}
return path;
}
-(int)executeScript:(PLKScript *)script
{
return [self.clojureScriptEngine executeSourceType:script.sourceType
value:script.sourceValue
expression:script.expression
printNilExpression:NO
inExitContext:YES];
}
@end