2011-04-23 44 views
1

我知道libexpect,但它的来源是巨大的,需要TCL。我希望能找到像ruby's'expect.rb'这样小的文件。有任何想法吗?有没有像Ruby的'expect.rb',但对于Objective C?

+0

您正在开发什么操作系统? – 2011-04-23 20:11:06

+0

我正在使用Mac OS X的文件管理器。 – neoneye 2011-04-23 20:12:32

+0

在这种情况下,我建议您通过NSTask使用'expect.rb'(或'/ usr/bin/expect');我没有意识到Cocoa的任何等价物,并且在Mac上没有与资源有关的理由。 – 2011-04-23 20:14:59

回答

1

解决了它。我根本没有运用libexpect。相反,我刚刚使用CocoaOniguruma将rubys'expect.rb'移植到objective-c。随意使用它,只要你喜欢。


/* 
NSFileHandle+Expect.h 
direct port of rubys 'expect.rb' to objective c 
by Simon Strandgaard on 26/04/11. 
public domain or BSD license 

requires CocoaOniguruma 
http://limechat.net/cocoaoniguruma/ 
*/ 
#import <Foundation/Foundation.h> 


@class ExpectResult; 

@interface NSFileHandle (Expect) 

/* 
wait for activity on the file descriptor. 
stops waiting if it takes longer than X seconds. 
*/ 
-(BOOL)waitForData:(float)seconds; 


/* 
buffer data on the filedescriptor until it matches the specified pattern. 
*/ 
-(ExpectResult*)expect:(NSString*)pattern timeout:(float)seconds debug:(BOOL)debug; 


/* 
write to filedescriptor 
*/ 
-(void)writeAsciiString:(NSString*)s; 

@end 

/* 
NSFileHandle+Expect.m 
direct port of rubys 'expect.rb' to objective c 
by Simon Strandgaard on 26/04/11. 
public domain or BSD license 

requires CocoaOniguruma 
http://limechat.net/cocoaoniguruma/ 
*/ 
#import "NSFileHandle+Expect.h" 
#import "OnigRegexp.h" 
#import "ExpectResult.h" 


@implementation NSFileHandle (Expect) 

-(BOOL)waitForData:(float)seconds { 
    struct timeval t; 
    t.tv_sec = (int)seconds; 
    float remain = seconds - t.tv_sec; 
    t.tv_usec = (int)(remain * 1000000); 


    int fd = [self fileDescriptor]; 
    fd_set ready; 
    FD_ZERO(&ready); 
    FD_SET((unsigned int)fd, &ready); 

    int res = select(fd+1, &ready, NULL, NULL, &t); 
    if(res == 0) { 
     return NO; // timeout 
    } 
    if(FD_ISSET(fd, &ready)) { 
     return YES; // we have data, one or more bytes is ready 
    } 
    return NO; // error 
} 


-(ExpectResult*)expect:(NSString*)pattern timeout:(float)seconds debug:(BOOL)debug { 
    OnigRegexp* regexp = [OnigRegexp compile:pattern]; 
    NSMutableString* buffer = [NSMutableString stringWithCapacity:100]; 
    ExpectResult* result = nil; 
    while(1) { 
     // wait until 1 byte is ready 
     if(![self waitForData:seconds]) { 
      // timeout or error 
      result = nil; 
      break; 
     } 

     // read out the byte and append it to the buffer 
     NSData* char_data = [self readDataOfLength:1]; 
     NSString* char_string = [[NSString alloc] initWithData:char_data encoding: NSASCIIStringEncoding]; 
     [buffer appendString:char_string]; 
     if(debug) { 
      NSLog(@"%s %@", _cmd, char_string); 
     } 
     [char_string release]; 

     // see if the new buffer now satisfies the pattern 
     OnigResult* r = [regexp search:buffer]; 
     if(r) { 
      result = [[[ExpectResult alloc] init] autorelease]; 
      result.bufferString = [NSString stringWithString:buffer]; 
      result.onigResult = r; 
      break; 
     } 
    } 

    return result; 
} 

-(void)writeAsciiString:(NSString*)s { 
    [self writeData:[s dataUsingEncoding:NSASCIIStringEncoding]]; 
} 

@end 

/* 
ExpectResult.h 
direct port of rubys 'expect.rb' to objective c 
by Simon Strandgaard on 26/04/11. 
public domain or BSD license 

requires CocoaOniguruma 
http://limechat.net/cocoaoniguruma/ 
*/ 
#import <Foundation/Foundation.h> 

@class OnigResult; 

@interface ExpectResult : NSObject { 
    NSString* m_buffer_string; 
    OnigResult* m_onig_result; 
} 
@property (nonatomic, retain) NSString* bufferString; 
@property (nonatomic, retain) OnigResult* onigResult; 

@end 

/* 
ExpectResult.h 
direct port of rubys 'expect.rb' to objective c 
by Simon Strandgaard on 26/04/11. 
public domain or BSD license 

requires CocoaOniguruma 
http://limechat.net/cocoaoniguruma/ 
*/ 
#import "ExpectResult.h" 
#import "OnigRegexp.h" 

@implementation ExpectResult 

@synthesize bufferString = m_buffer_string; 
@synthesize onigResult = m_onig_result; 

-(void)dealloc { 
    self.bufferString = nil; 
    self.onigResult = nil; 
    [super dealloc]; 
} 

@end 

NSArray* arguments = [NSArray arrayWithObject:@"ftp.ruby-lang.org"]; 

NSTask* task = [[[NSTask alloc] init] autorelease]; 
[task setLaunchPath:@"/usr/bin/ftp"]; 

NSPipe* readPipe = [NSPipe pipe]; 
NSPipe* writePipe = [NSPipe pipe]; 

[task setStandardInput: writePipe]; 
[task setStandardOutput: readPipe]; 
[task setArguments:arguments]; 

[task launch]; 

NSFileHandle* readHandle = [readPipe fileHandleForReading]; 
NSFileHandle* writeHandle = [writePipe fileHandleForWriting]; 

{ 
    NSString* pattern = @"^Name.*: "; 
    [readHandle expect:pattern timeout:5 debug:YES]; 
    [writeHandle writeAsciiString:@"ftp\n"]; 
} 
{ 
    NSString* pattern = @"word:"; 
    [readHandle expect:pattern timeout:5 debug:YES]; 
    [writeHandle writeAsciiString:@"[email protected]\n"]; 
} 
{ 
    NSString* pattern = @"> "; 
    [readHandle expect:pattern timeout:5 debug:YES]; 
    [writeHandle writeAsciiString:@"cd pub/ruby\n"]; 
} 
{ 
    NSString* pattern = @"> "; 
    [readHandle expect:pattern timeout:5 debug:YES]; 
    [writeHandle writeAsciiString:@"dir\n"]; 
} 
{ 
    NSString* pattern = @"> "; 
    ExpectResult* er = [readHandle expect:pattern timeout:5 debug:YES]; 

    NSLog(@"%s versions: %@", _cmd, er.bufferString); 

    [writeHandle writeAsciiString:@"quit\n"]; 
} 

output: 
drwxrwxr-x 2 0  103   4096 Jul 06 2009 1.0 
drwxrwxr-x 2 0  103   4096 Aug 04 2003 1.1a 
drwxrwxr-x 2 0  103   4096 Jul 16 1998 1.1b 
drwxrwxr-x 2 0  103   4096 Jan 18 1999 1.1c 
drwxrwxr-x 2 0  103   54 Dec 25 1998 1.1d 
drwxrwxr-x 2 0  103   4096 Sep 18 1999 1.2 
drwxrwxr-x 2 0  103   4096 Sep 18 1999 1.3 
drwxrwxr-x 2 0  103   4096 Apr 05 2001 1.4 
drwxrwxr-x 2 0  103   4096 Sep 20 2005 1.6 
drwxrwxr-x 2 0  103   8192 Feb 18 12:49 1.8 
drwxrwxr-x 2 0  103   4096 Feb 18 13:39 1.9 
drwxrwxr-t 6 0  103   89 Jun 15 2004 binaries 
drwxrwxr-x 2 1027  100   12288 Apr 05 15:12 doc 
lrwxrwxrwx 1 1023  100   27 Sep 23 2010 ruby-1.8.6-p420.tar.bz2 -> 
1

您可能会考虑将macruby用于该项目。

+0

没有解决方案。我正在研究目标c中的文件管理器。我没有为文件管理器编写脚本。如果它是一个脚本,我肯定会使用红宝石。 btw:文件管理器的单元测试使用ruby,并使用expect.rb。 – neoneye 2011-04-23 21:14:11

+0

不是脚本[链接到文章](http://developer.apple.com/library/mac/#featuredarticles/UsingMacRuby/_index.html):“使用Ruby编写Cocoa应用程序不仅是可能的,但也很容易,性能,这要归功于MacRuby及其与Mac OS X核心技术的紧密集成“ – seph 2011-04-24 11:39:17

+0

可能的展示瓶塞:需要Snow Leopard,尚未1.0(几乎) – seph 2011-04-24 11:49:40

相关问题