Skip to content

Commit

Permalink
• renamed and added resp. NSString's methods from "runBashCommandWith…
Browse files Browse the repository at this point in the history
…Environment" to "evaluateAsBashCommandWithEnvironment" and "runAsBashCommandWithEnvironment" resp.

- runAs... will run it without returning stdout for speed
- evaluateAs... will run it and return stdout
- added further placeholder methods like runAsBashCommand or runAsBashCommandAndError: etc.
- if no NSError will be passed write stderr to /dev/null

git-svn-id: https://svn.r-project.org/R-packages/trunk/Mac-GUI@6060 694ef91d-65df-0310-b7bb-92e67a308ead
  • Loading branch information
Hans-Jörg Bibiko committed Feb 2, 2012
1 parent f8eafed commit 2533530
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 105 deletions.
16 changes: 14 additions & 2 deletions NSString_RAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,19 @@

+ (NSString*)stringWithNewUUID;

- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path callerInstance:(id)caller contextInfo:(NSDictionary*)contextInfo error:(NSError**)theError;
- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path error:(NSError**)theError;
- (NSString *)evaluateAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironment
atPath:(NSString*)path
callerInstance:(id)caller
contextInfo:(NSDictionary*)contextInfo
error:(NSError**)theError ignoreOutput:(BOOL)ignoreOutput;
- (NSString *)evaluateAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironment
atPath:(NSString*)path error:(NSError**)theError;
- (NSString *)evaluateAsBashCommandAndError:(NSError**)theError;
- (NSString *)evaluateAsBashCommand;

- (void)runAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atPath:(NSString*)path callerInstance:(id)caller contextInfo:(NSDictionary*)contextInfo error:(NSError**)theError;
- (void)runAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atPath:(NSString*)path error:(NSError**)theError;
- (void)runAsBashCommandAndError:(NSError**)theError;
- (void)runAsBashCommand;

@end
136 changes: 111 additions & 25 deletions NSString_RAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ + (NSString*)stringWithNewUUID
* @param theError If not nil and the bash command failed it contains the returned error message as NSLocalizedDescriptionKey
*
*/
- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path callerInstance:(id)caller contextInfo:(NSDictionary*)contextInfo error:(NSError**)theError
- (NSString *)evaluateAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atPath:(NSString*)path callerInstance:(id)caller contextInfo:(NSDictionary*)contextInfo error:(NSError**)theError ignoreOutput:(BOOL)ignoreOutput
{

NSFileManager *fm = [NSFileManager defaultManager];
Expand Down Expand Up @@ -134,14 +134,14 @@ - (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCu
else
[theEnv setDictionary:[[NSProcessInfo processInfo] environment]];

[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionNone] forKey:kBASHTaskShellVariableExitNone];
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceSection] forKey:kBASHTaskShellVariableExitReplaceSelection];
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceContent] forKey:kBASHTaskShellVariableExitReplaceContent];
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionInsertAsText] forKey:kBASHTaskShellVariableExitInsertAsText];
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionInsertAsSnippet] forKey:kBASHTaskShellVariableExitInsertAsSnippet];
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionShowAsHTML] forKey:kBASHTaskShellVariableExitShowAsHTML];
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionShowAsTextTooltip] forKey:kBASHTaskShellVariableExitShowAsTextTooltip];
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionShowAsHTMLTooltip] forKey:kBASHTaskShellVariableExitShowAsHTMLTooltip];
// [theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionNone] forKey:kBASHTaskShellVariableExitNone];
// [theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceSection] forKey:kBASHTaskShellVariableExitReplaceSelection];
// [theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceContent] forKey:kBASHTaskShellVariableExitReplaceContent];
// [theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionInsertAsText] forKey:kBASHTaskShellVariableExitInsertAsText];
// [theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionInsertAsSnippet] forKey:kBASHTaskShellVariableExitInsertAsSnippet];
// [theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionShowAsHTML] forKey:kBASHTaskShellVariableExitShowAsHTML];
// [theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionShowAsTextTooltip] forKey:kBASHTaskShellVariableExitShowAsTextTooltip];
// [theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionShowAsHTMLTooltip] forKey:kBASHTaskShellVariableExitShowAsHTMLTooltip];

if(theEnv != nil && [theEnv count])
[bashTask setEnvironment:theEnv];
Expand All @@ -150,18 +150,20 @@ - (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCu
[bashTask setCurrentDirectoryPath:path];

// STDOUT will be redirected to kBASHTaskOutputFilePath in order to avoid nasty pipe programming due to block size reading
if([shellEnvironment objectForKey:kBASHTaskShellVariableInputFilePathh])
[bashTask setArguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"%@ > %@ < %@", [scriptHeaderArguments componentsJoinedByString:@" "], stdoutFilePath, [shellEnvironment objectForKey:kBASHTaskShellVariableInputFilePathh]], nil]];
if([shellEnvironment objectForKey:kBASHTaskShellVariableInputFilePath])
[bashTask setArguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"%@ > %@ < %@", [scriptHeaderArguments componentsJoinedByString:@" "], stdoutFilePath, [shellEnvironment objectForKey:kBASHTaskShellVariableInputFilePath]], nil]];
else
[bashTask setArguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"%@ > %@", [scriptHeaderArguments componentsJoinedByString:@" "], stdoutFilePath], nil]];


NSFileHandle *stderr_file = nil;
NSPipe *stderr_pipe = nil;
if(!nonWaitingMode) {
if(!nonWaitingMode && theError != NULL) {
stderr_pipe = [NSPipe pipe];
[bashTask setStandardError:stderr_pipe];
stderr_file = [stderr_pipe fileHandleForReading];
} else {
[bashTask setStandardError:[NSFileHandle fileHandleForWritingAtPath:@"/dev/null"]];
}
[bashTask launch];

Expand Down Expand Up @@ -206,12 +208,12 @@ - (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCu
[NSApp activateIgnoringOtherApps:YES];

NSInteger status = [bashTask terminationStatus];
NSData *errdata = [stderr_file readDataToEndOfFile];
NSData *errdata = nil;

// Check STDERR
if([errdata length] && (status < kBASHTaskRedirectActionNone || status > kBASHTaskRedirectActionLastCode)) {
if(theError != NULL && [errdata length] && (status < kBASHTaskRedirectActionNone || status > kBASHTaskRedirectActionLastCode)) {
[fm removeItemAtPath:stdoutFilePath error:nil];

if(stderr_file) [stderr_file readDataToEndOfFile];
if(status == 9 || userTerminated) return @"";
if(theError != NULL) {
NSMutableString *errMessage = [[[NSMutableString alloc] initWithData:errdata encoding:NSUTF8StringEncoding] autorelease];
Expand All @@ -222,12 +224,16 @@ - (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCu
errMessage,
NSLocalizedDescriptionKey,
nil]] autorelease];
} else {
NSBeep();
}
return @"";
}


if(ignoreOutput && theError == NULL) {
if (bashTask) [bashTask release];
[fm removeItemAtPath:stdoutFilePath error:nil];
return @"";
}

// Read STDOUT saved to file
if([fm fileExistsAtPath:stdoutFilePath isDirectory:nil]) {
NSString *stdoutContent = [NSString stringWithContentsOfFile:stdoutFilePath encoding:NSUTF8StringEncoding error:nil];
Expand All @@ -239,16 +245,17 @@ - (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCu
} else {
if(theError != NULL) {
if(status == 9 || userTerminated) return @"";
NSMutableString *errMessage = [[[NSMutableString alloc] initWithData:errdata encoding:NSUTF8StringEncoding] autorelease];
[errMessage replaceOccurrencesOfString:kBASHTaskScriptCommandFilePath withString:@"" options:NSLiteralSearch range:NSMakeRange(0, [errMessage length])];
*theError = [[[NSError alloc] initWithDomain:NSPOSIXErrorDomain
if(stderr_file) {
[stderr_file readDataToEndOfFile];
NSMutableString *errMessage = [[[NSMutableString alloc] initWithData:errdata encoding:NSUTF8StringEncoding] autorelease];
[errMessage replaceOccurrencesOfString:kBASHTaskScriptCommandFilePath withString:@"" options:NSLiteralSearch range:NSMakeRange(0, [errMessage length])];
*theError = [[[NSError alloc] initWithDomain:NSPOSIXErrorDomain
code:status
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
errMessage,
NSLocalizedDescriptionKey,
nil]] autorelease];
} else {
NSBeep();
}
}
if(status > kBASHTaskRedirectActionNone && status <= kBASHTaskRedirectActionLastCode)
return stdoutContent;
Expand Down Expand Up @@ -278,10 +285,89 @@ - (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCu
* @param theError If not nil and the bash command failed it contains the returned error message as NSLocalizedDescriptionKey
*
*/
- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path error:(NSError**)theError
- (NSString *)evaluateAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atPath:(NSString*)path error:(NSError**)theError
{
return [self evaluateAsBashCommandWithEnvironment:shellEnvironment atPath:path callerInstance:nil contextInfo:nil error:theError ignoreOutput:NO];
}

/**
* Run self as BASH command(s) and return the result.
* This task can be interrupted by pressing ⌘.
*
* @param theError If not nil and the bash command failed it contains the returned error message as NSLocalizedDescriptionKey
*
*/
- (NSString *)evaluateAsBashCommandAndError:(NSError**)theError
{
return [self runBashCommandWithEnvironment:shellEnvironment atCurrentDirectoryPath:path callerInstance:nil contextInfo:nil error:theError];
return [self evaluateAsBashCommandWithEnvironment:nil atPath:nil callerInstance:nil contextInfo:nil error:theError ignoreOutput:NO];
}

/**
* Run self as BASH command(s) and return the result.
* This task can be interrupted by pressing ⌘.
*
*/
- (NSString *)evaluateAsBashCommand
{
return [self evaluateAsBashCommandWithEnvironment:nil atPath:nil callerInstance:nil contextInfo:nil error:nil ignoreOutput:NO];
}

/**
* Run self as BASH command(s).
* This task can be interrupted by pressing ⌘.
*
* @param shellEnvironment A dictionary of environment variable values whose keys are the variable names.
*
* @param path The current directory for the bash command. If path is nil, the current directory is inherited from the process that created the receiver (normally /).
*
* @param caller The SPDatabaseDocument which invoked that command to register the command for cancelling; if nil the command won't be registered.
*
* @param name The menu title of the command.
*
* @param theError If not nil and the bash command failed it contains the returned error message as NSLocalizedDescriptionKey
*
*/
- (void)runAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atPath:(NSString*)path callerInstance:(id)caller contextInfo:(NSDictionary*)contextInfo error:(NSError**)theError
{
[self evaluateAsBashCommandWithEnvironment:shellEnvironment atPath:path callerInstance:caller contextInfo:contextInfo error:theError ignoreOutput:YES];
}

/**
* Run self as BASH command(s).
* This task can be interrupted by pressing ⌘.
*
* @param shellEnvironment A dictionary of environment variable values whose keys are the variable names.
*
* @param path The current directory for the bash command. If path is nil, the current directory is inherited from the process that created the receiver (normally /).
*
* @param theError If not nil and the bash command failed it contains the returned error message as NSLocalizedDescriptionKey
*
*/
- (void)runAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atPath:(NSString*)path error:(NSError**)theError
{
[self evaluateAsBashCommandWithEnvironment:shellEnvironment atPath:path callerInstance:nil contextInfo:nil error:theError ignoreOutput:YES];
}

/**
* Run self as BASH command(s).
* This task can be interrupted by pressing ⌘.
*
* @param theError If not nil and the bash command failed it contains the returned error message as NSLocalizedDescriptionKey
*
*/
- (void)runAsBashCommandAndError:(NSError**)theError
{
[self evaluateAsBashCommandWithEnvironment:nil atPath:nil callerInstance:nil contextInfo:nil error:theError ignoreOutput:YES];
}

/**
* Run self as BASH command(s).
* This task can be interrupted by pressing ⌘.
*
*/
- (void)runAsBashCommand
{
[self evaluateAsBashCommandWithEnvironment:nil atPath:nil callerInstance:nil contextInfo:nil error:nil ignoreOutput:YES];
}

@end
2 changes: 1 addition & 1 deletion PreferenceKeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
#define kBASHFileInternalexecutionUUID @"bashexeUUID"
#define kBASHTaskOutputFilePath @"/tmp/R_BASH_OUTPUT"
#define kBASHTaskScriptCommandFilePath @"/tmp/R_BASH_SCRIPT_COMMAND"
#define kBASHTaskShellVariableInputFilePathh @"/tmp/R_BASH_INPUT"
#define kBASHTaskShellVariableInputFilePath @"/tmp/R_BASH_INPUT"
#define kBASHTaskRedirectActionNone 200
#define kBASHTaskRedirectActionReplaceSection 201
#define kBASHTaskRedirectActionReplaceContent 202
Expand Down
24 changes: 10 additions & 14 deletions RDocument.m
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ - (BOOL) checkRdDocumentWithFilePath:(NSString*)inputFile reportSuccess:(BOOL)re

NSString *convCmd = [NSString stringWithFormat:@"R --vanilla -q --slave --encoding=UTF-8 -e 'tools:::checkRd(\"%@\")'", inputFile];
NSError *bashError = nil;
NSString *errMessage = [convCmd runBashCommandWithEnvironment:nil atCurrentDirectoryPath:nil error:&bashError];
NSString *errMessage = [convCmd evaluateAsBashCommandAndError:&bashError];

if(bashError != nil) {
if([bashError code] == 1) {
Expand Down Expand Up @@ -590,7 +590,7 @@ - (void) insertRdDataTemplate
[myWinCtrl setStatusLineText:[NSString stringWithFormat:@"%@", NLS(@"press ⌘. to cancel")]];

NSError *bashError = nil;
NSString *templateStr = [@"R --vanilla --slave -e 'cat(unlist(prompt(Formaldehyde,NA)), sep=\"§\")'" runBashCommandWithEnvironment:nil atCurrentDirectoryPath:nil error:&bashError];
NSString *templateStr = [@"R --vanilla --slave -e 'cat(unlist(prompt(Formaldehyde,NA)), sep=\"§\")'" evaluateAsBashCommandAndError:&bashError];

[myWinCtrl setStatusLineText:@""];

Expand Down Expand Up @@ -631,7 +631,7 @@ - (void) insertRdFunctionTemplate
[myWinCtrl setStatusLineText:[NSString stringWithFormat:@"%@", NLS(@"press ⌘. to cancel")]];

NSError *bashError = nil;
NSString *templateStr = [@"R --vanilla --slave -e 'cat(unlist(prompt(mean.POSIXct,NA)), sep=\"§\")'" runBashCommandWithEnvironment:nil atCurrentDirectoryPath:nil error:&bashError];
NSString *templateStr = [@"R --vanilla --slave -e 'cat(unlist(prompt(mean.POSIXct,NA)), sep=\"§\")'" evaluateAsBashCommandAndError:&bashError];

[myWinCtrl setStatusLineText:@""];

Expand Down Expand Up @@ -675,21 +675,17 @@ - (BOOL) convertRd2PDF
// Try to find the path to the default tex distribution
NSString *texPath = @"";
[myWinCtrl setStatusLineText:[NSString stringWithFormat:@"%@", NLS(@"press ⌘. to cancel")]];
NSString *aPath = [@"which tex" runBashCommandWithEnvironment:nil atCurrentDirectoryPath:nil error:&bashError];
NSString *aPath = [@"which tex" evaluateAsBashCommand];
[myWinCtrl setStatusLineText:@""];
if(bashError == nil && aPath && [aPath length]) {
if(aPath && [aPath length]) {
;
} else {
if(bashError) SLog(@"Couldn't find tex %@", [[bashError userInfo] objectForKey:NSLocalizedDescriptionKey]);
bashError = nil;
[myWinCtrl setStatusLineText:[NSString stringWithFormat:@"%@", NLS(@"press ⌘. to cancel")]];
aPath = [@"eval `/usr/libexec/path_helper -s` && dirname `which tex`"
runBashCommandWithEnvironment:nil atCurrentDirectoryPath:nil error:&bashError];
aPath = [@"eval `/usr/libexec/path_helper -s` && dirname `which tex`" evaluateAsBashCommand];
[myWinCtrl setStatusLineText:@""];
if(bashError == nil && aPath && [aPath length]) {
if(aPath && [aPath length]) {
texPath = [NSString stringWithFormat:@"export PATH=$PATH:%@", aPath];
}
else if(bashError) SLog(@"path_helper couldn't find a tex environment %@", [[bashError userInfo] objectForKey:NSLocalizedDescriptionKey]);
}

NSString *tempName = [NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"%.0f.", [NSDate timeIntervalSinceReferenceDate] * 1000.0]];
Expand All @@ -714,7 +710,7 @@ - (BOOL) convertRd2PDF
bashError = nil;

[myWinCtrl setStatusLineText:[NSString stringWithFormat:@"%@ (%@)", NLS(@"Rd → PDF…"), NLS(@"press ⌘. to cancel")]];
(void)[convCmd runBashCommandWithEnvironment:nil atCurrentDirectoryPath:nil error:&bashError];
[convCmd runAsBashCommandAndError:&bashError];
[myWinCtrl setStatusLineText:@""];

NSFileManager *man = [NSFileManager defaultManager];
Expand Down Expand Up @@ -774,7 +770,7 @@ - (BOOL) convertRd2HTML

if(!Rhome || ![Rhome length]) {
[myWinCtrl setStatusLineText:[NSString stringWithFormat:@"%@", NLS(@"press ⌘. to cancel")]];
Rhome = [@"R --slave --vanilla -e 'cat(R.home())'" runBashCommandWithEnvironment:nil atCurrentDirectoryPath:nil error:nil];
Rhome = [@"R --slave --vanilla -e 'cat(R.home())'" evaluateAsBashCommand];
[myWinCtrl setStatusLineText:@""];
}

Expand All @@ -800,7 +796,7 @@ - (BOOL) convertRd2HTML

[myWinCtrl setStatusLineText:[NSString stringWithFormat:@"%@ (%@)", NLS(@"Rd → HTML…"), NLS(@"press ⌘. to cancel")]];
NSString *convCmd = [NSString stringWithFormat:@"R CMD Rdconv -t html '%@' 2>/dev/null | perl -pe 's!R.css!%@!'> '%@'", inputFile, RhomeCSS, htmlOutputFile];
[convCmd runBashCommandWithEnvironment:nil atCurrentDirectoryPath:nil error:&error];
[convCmd evaluateAsBashCommandAndError:&error];
[myWinCtrl setStatusLineText:@""];

// Try to check if htmlOutputFile has content; if not don't come up with an empty window
Expand Down
Loading

0 comments on commit 2533530

Please sign in to comment.