|
TOC | PREV | NEXT
/* SDLogTask.h created by andrew on Thu 30-Apr-1998 */
//
// A wrapper of some intense multi-threaded code
// To allow you to spawn a task and see the errors
//
#import <AppKit/AppKit.h>
@interface SDLogTask : NSObject
{
id owner;
NSTextView *logText;
NSTask *task;
BOOL includeStandardOutput;
NSPipe *standardErrorPipe;
NSPipe *standardOutputPipe;
NSFileHandle *standardErrorHandle;
NSFileHandle *standardOutputHandle;
}
//
// executable is full path to program
// args is an array of strings of the arguments
// send in an NSTextView if you want console behaviour
// includeStandardOut: is YES if you also want stdout logged to Text
//
- initAndLaunchWithArgs:(NSArray *)args executable:(NSString *)pathToExe directory:(NSString *)dir logToText:(NSTextView *)text includeStandardOutput:(BOOL)includeStandardOut owner:anOwner;
@end
//
// SDLogTask.m
//
/* SDLogTask.m created by andrew on Thu 30-Apr-1998 */
#import "SDLogTask.h"
// kudos to bbum@codefab.com for helping me fix IO:
#import "NSFileHandle_CFRNonBlockingIO.h"
//
// If you want notification when the task completes
// implement this method in the "owner" class
//
@interface NSObject(SDLogTask_Delegate)
- (void)taskTerminated:(BOOL)success;
@end
@implementation SDLogTask
//
// Methods to make it easy to spew feedback to user:
//
#define END_RANGE NSMakeRange([[logText string]length],0)
- (void)appendString:(NSString *)string newLine:(BOOL)newLine
{
[logText replaceCharactersInRange:END_RANGE withString:string];
if (newLine)
[logText replaceCharactersInRange:END_RANGE withString:@"\n"];
else
[logText replaceCharactersInRange:END_RANGE withString:@" "];
if ([[logText window] isVisible]) {
[logText scrollRangeToVisible:END_RANGE];
}
}
- (void)outputData:(NSData *)data
{
[self appendString:[[[NSString alloc]initWithData:data encoding:[NSString defaultCStringEncoding]]autorelease] newLine:YES];
}
- (void) processAvailableData;
{
NSData *data;
BOOL dataProcessed;
dataProcessed = NO;
data = [standardErrorHandle availableDataNonBlocking];
if ( (data != nil) && ([data length] != 0) ) {
[self outputData:data];
dataProcessed = YES;
}
if (includeStandardOutput) {
data = [standardOutputHandle availableDataNonBlocking];
if ( (data != nil) && ([data length] != 0) ) {
[self outputData:data];
dataProcessed = YES;
}
}
if ([task isRunning] == YES) {
if (dataProcessed == YES)
[self performSelector: @selector(processAvailableData)
withObject: nil afterDelay: .1];
else
[self performSelector: @selector(processAvailableData)
withObject: nil afterDelay: 2.5];
}
}
- (void) outputInfoAtStart:(NSString *)pathToExe args:(NSArray *)args
{
int i;
// clear it out from last time:
[logText setString:@""];
[self appendString:pathToExe newLine:NO];
for (i = 0; i < [args count]; i++)
[self appendString:[args objectAtIndex:i] newLine:NO];
[self appendString:@"\n" newLine:YES];
}
- initAndLaunchWithArgs:(NSArray *)args executable:(NSString *)pathToExe directory:(NSString *)dir logToText:(NSTextView *)text includeStandardOutput:(BOOL)includeStandardOut owner:anOwner
{
[super init];
logText = text;
includeStandardOutput = includeStandardOut;
owner = anOwner;
standardErrorPipe = [NSPipe pipe];
standardErrorHandle = [standardErrorPipe fileHandleForReading];
if (includeStandardOutput) {
standardOutputPipe = [NSPipe pipe];
standardOutputHandle = [standardOutputPipe fileHandleForReading];
}
task = [[NSTask alloc] init];
[task setArguments:args];
[task setCurrentDirectoryPath:dir];
[task setLaunchPath:pathToExe];
[task setStandardError:standardErrorPipe];
if (includeStandardOutput) [task setStandardOutput:standardOutputPipe];
[self outputInfoAtStart:pathToExe args:args];
[self performSelector: @selector(processAvailableData) withObject: nil afterDelay: 1.0];
// HERE WE GO: spin off a thread to do this:
[task launch];
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(checkATaskStatus:)
name: NSTaskDidTerminateNotification
object: task];
return self;
}
#define TASK_SUCCEEDED NSLocalizedStringFromTable(@"\nJob SUCCEEDED!\n", @"GIFfun", "message when task is successful")
#define TASK_FAILED NSLocalizedStringFromTable(@"\nJob FAILED!\n\nPlease see log.", @"GIFfun", "when the task fails...")
- (void)checkATaskStatus:(NSNotification *)aNotification
{
int status = [[aNotification object] terminationStatus];
if (status == 0 /* STANDARD SILLY UNIX RETURN VALUE */) {
[self appendString:TASK_SUCCEEDED newLine:YES];
} else {
[self appendString:TASK_FAILED newLine:YES];
[[logText window] orderFront:self];
}
if ([owner respondsToSelector:@selector(taskTerminated:)])
[owner taskTerminated:(status == 0)];
}
@end
TOC | PREV | NEXT
Created by Stone Design's Create on 4/30/1998
|
|