Look like working now.
This commit is contained in:
62
Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.h
generated
Normal file
62
Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.h
generated
Normal file
@ -0,0 +1,62 @@
|
||||
// BRLOptionParser.h
|
||||
//
|
||||
// Copyright © 2013–2015 Stephen Celis (<stephen@stephencelis.com>)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
@import Foundation;
|
||||
|
||||
|
||||
typedef void (^BRLOptionParserOptionBlock)();
|
||||
typedef void (^BRLOptionParserOptionBlockWithArgument)(NSString *value);
|
||||
|
||||
|
||||
static NSString *const BRLOptionParserErrorDomain = @"BRLOptionParserErrorDomain";
|
||||
|
||||
|
||||
typedef NS_ENUM(NSUInteger, BRLOptionParserErrorCode) {
|
||||
BRLOptionParserErrorCodeUnrecognized = 1,
|
||||
BRLOptionParserErrorCodeRequired
|
||||
};
|
||||
|
||||
|
||||
@interface BRLOptionParser : NSObject
|
||||
|
||||
+ (instancetype)parser;
|
||||
+ (instancetype)longOnlyParser;
|
||||
|
||||
@property (nonatomic, getter = isLongOnly) BOOL longOnly;
|
||||
|
||||
@property (nonatomic, copy) NSString *banner;
|
||||
|
||||
- (void)setBanner:(NSString *)banner, ...;
|
||||
|
||||
- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description block:(BRLOptionParserOptionBlock)block;
|
||||
- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description blockWithArgument:(BRLOptionParserOptionBlockWithArgument)blockWithArgument;
|
||||
|
||||
- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description value:(BOOL *)value;
|
||||
- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description argument:(NSString *__strong *)argument;
|
||||
|
||||
- (void)addSeparator;
|
||||
- (void)addSeparator:(NSString *)separator;
|
||||
|
||||
- (BOOL)parseArgc:(int)argc argv:(const char **)argv error:(NSError **)error;
|
||||
|
||||
@end
|
306
Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.m
generated
Normal file
306
Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.m
generated
Normal file
@ -0,0 +1,306 @@
|
||||
// BRLOptionParser.m
|
||||
//
|
||||
// Copyright © 2013–2015 Stephen Celis (<stephen@stephencelis.com>)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
#import "BRLOptionParser.h"
|
||||
#import <getopt.h>
|
||||
|
||||
|
||||
typedef NS_ENUM(NSUInteger, BRLOptionArgument) {
|
||||
BRLOptionArgumentNone = no_argument,
|
||||
BRLOptionArgumentRequired = required_argument
|
||||
};
|
||||
|
||||
|
||||
@interface BRLOption : NSObject
|
||||
|
||||
@property (assign) BRLOptionArgument argument;
|
||||
@property (assign) char * name;
|
||||
@property (assign) unichar flag;
|
||||
@property (strong) NSString *description;
|
||||
@property (copy) id block;
|
||||
|
||||
+ (instancetype)optionWithName:(char *)name flag:(unichar)flag description:(NSString *)description block:(BRLOptionParserOptionBlock)block;
|
||||
+ (instancetype)optionWithName:(char *)name flag:(unichar)flag description:(NSString *)description blockWithArgument:(BRLOptionParserOptionBlockWithArgument)blockWithArgument;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation BRLOption
|
||||
|
||||
@synthesize description = _description;
|
||||
|
||||
+ (instancetype)optionWithName:(char *)name flag:(unichar)flag description:(NSString *)description block:(BRLOptionParserOptionBlock)block
|
||||
{
|
||||
BRLOption *option = [[self alloc] initWithName:name flag:flag description:description argument:BRLOptionArgumentNone block:block];
|
||||
return option;
|
||||
}
|
||||
|
||||
+ (instancetype)optionWithName:(char *)name flag:(unichar)flag description:(NSString *)description blockWithArgument:(BRLOptionParserOptionBlockWithArgument)blockWithArgument
|
||||
{
|
||||
BRLOption *option = [[self alloc] initWithName:name flag:flag description:description argument:BRLOptionArgumentRequired block:blockWithArgument];
|
||||
return option;
|
||||
}
|
||||
|
||||
- (instancetype)initWithName:(char *)name flag:(unichar)flag description:(NSString *)description argument:(BRLOptionArgument)argument block:(id)block
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_argument = argument;
|
||||
_name = name;
|
||||
_flag = flag;
|
||||
_block = block;
|
||||
_description = description;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface BRLOptionParser ()
|
||||
|
||||
@property NSMutableArray *options;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation BRLOptionParser
|
||||
|
||||
+ (instancetype)parser
|
||||
{
|
||||
return [self new];
|
||||
}
|
||||
|
||||
+ (instancetype)longOnlyParser
|
||||
{
|
||||
BRLOptionParser *parser = [self parser];
|
||||
if (parser) {
|
||||
parser.longOnly = YES;
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
[self setBanner:@"usage: %@ [options]", [NSProcessInfo processInfo].processName];
|
||||
_options = [NSMutableArray new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setBanner:(NSString *)banner, ...
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, banner);
|
||||
_banner = [[NSString alloc] initWithFormat:banner arguments:args];
|
||||
va_end(args);
|
||||
return;
|
||||
}
|
||||
|
||||
- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description block:(BRLOptionParserOptionBlock)block
|
||||
{
|
||||
[self.options addObject:[BRLOption optionWithName:option flag:flag description:description block:block]];
|
||||
}
|
||||
|
||||
- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description blockWithArgument:(BRLOptionParserOptionBlockWithArgument)blockWithArgument
|
||||
{
|
||||
[self.options addObject:[BRLOption optionWithName:option flag:flag description:description blockWithArgument:blockWithArgument]];
|
||||
}
|
||||
|
||||
- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description value:(BOOL *)value
|
||||
{
|
||||
[self addOption:option flag:flag description:description block:^{
|
||||
*value = YES;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description argument:(NSString *__strong *)argument
|
||||
{
|
||||
[self addOption:option flag:flag description:description blockWithArgument:^(NSString *value) {
|
||||
*argument = value;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)addSeparator
|
||||
{
|
||||
[self addSeparator:nil];
|
||||
}
|
||||
|
||||
- (void)addSeparator:(NSString *)separator
|
||||
{
|
||||
if (separator == nil) {
|
||||
separator = @"";
|
||||
}
|
||||
[self.options addObject:separator];
|
||||
}
|
||||
|
||||
- (BOOL)parseArgc:(int)argc argv:(const char **)argv error:(NSError *__autoreleasing *)error
|
||||
{
|
||||
NSMapTable *mapTable = NSCreateMapTable(NSIntegerMapKeyCallBacks, NSNonRetainedObjectMapValueCallBacks, self.options.count);
|
||||
|
||||
NSUInteger i = 0;
|
||||
NSUInteger c = 0;
|
||||
|
||||
struct option * long_options = malloc((self.options.count + 1) * sizeof(struct option));
|
||||
char * short_options = malloc(((self.options.count * 2) + 1) * sizeof(char));
|
||||
|
||||
for (id each in self.options) {
|
||||
if (![each isKindOfClass:[BRLOption class]]) {
|
||||
continue;
|
||||
}
|
||||
BRLOption *option = each;
|
||||
if (option.name) {
|
||||
NSMapInsert(mapTable, (const void *)option.name, (__bridge void *)option);
|
||||
long_options[i++] = (struct option){option.name, option.argument, NULL, option.flag};
|
||||
}
|
||||
if (option.flag) {
|
||||
NSMapInsert(mapTable, (const void *)(NSUInteger)option.flag, (__bridge void *)option);
|
||||
short_options[c++] = option.flag;
|
||||
if (option.argument == BRLOptionArgumentRequired) {
|
||||
short_options[c++] = ':';
|
||||
};
|
||||
}
|
||||
}
|
||||
long_options[i] = (struct option){0, 0, 0, 0};
|
||||
short_options[c] = '\0';
|
||||
|
||||
int ch = 0;
|
||||
int long_options_index = 0;
|
||||
|
||||
opterr = 0;
|
||||
|
||||
int (* getopt_long_method)(int, char * const *, const char *, const struct option *, int *);
|
||||
getopt_long_method = self.isLongOnly ? &getopt_long_only : &getopt_long;
|
||||
|
||||
int cached_optind = optind;
|
||||
while ((ch = getopt_long_method(argc, (char **)argv, short_options, long_options, &long_options_index)) != -1) {
|
||||
@try {
|
||||
BRLOption *option = nil;
|
||||
|
||||
switch (ch) {
|
||||
case '?': {
|
||||
if (error) {
|
||||
// I wish this could be done more cleanly, but getopt doesn't appear to expose the current failing option as originally input.
|
||||
NSString *arg = [NSString stringWithUTF8String:argv[cached_optind]];
|
||||
if ([arg hasPrefix:[self longPrefix]]) {
|
||||
arg = [arg componentsSeparatedByString:@"="].firstObject;
|
||||
} else if (optopt) {
|
||||
arg = [NSString stringWithFormat:@"-%c", optopt];
|
||||
}
|
||||
|
||||
if (optopt) {
|
||||
option = (__bridge BRLOption *)NSMapGet(mapTable, (const void *)(NSUInteger)optopt);
|
||||
} else {
|
||||
NSString *longOption = [NSString stringWithFormat:@"%@%s", [self longPrefix], long_options[long_options_index].name];
|
||||
if ([arg isEqualToString:longOption]) {
|
||||
option = (__bridge BRLOption *)NSMapGet(mapTable, (const void *)long_options[long_options_index].name);
|
||||
}
|
||||
}
|
||||
|
||||
if (option && option.argument == BRLOptionArgumentRequired) {
|
||||
*error = [NSError errorWithDomain:BRLOptionParserErrorDomain code:BRLOptionParserErrorCodeRequired userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"option `%@' requires an argument", arg]}];
|
||||
} else {
|
||||
*error = [NSError errorWithDomain:BRLOptionParserErrorDomain code:BRLOptionParserErrorCodeUnrecognized userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"unrecognized option `%@'", arg]}];
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
break;
|
||||
}
|
||||
case ':':
|
||||
|
||||
break;
|
||||
case 0:
|
||||
option = (__bridge BRLOption *)NSMapGet(mapTable, (const void *)long_options[long_options_index].name);
|
||||
break;
|
||||
default: {
|
||||
option = (__bridge BRLOption *)NSMapGet(mapTable, (const void *)(NSUInteger)ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (option.argument == BRLOptionArgumentRequired) {
|
||||
BRLOptionParserOptionBlockWithArgument block = option.block;
|
||||
block([NSString stringWithUTF8String:optarg]);
|
||||
} else {
|
||||
BRLOptionParserOptionBlock block = option.block;
|
||||
block();
|
||||
}
|
||||
} @finally {
|
||||
cached_optind = optind;
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
NSMutableString *(^trimLine)(NSMutableString *) = ^NSMutableString *(NSMutableString *line) {
|
||||
NSRange range = [line rangeOfCharacterFromSet:[[NSCharacterSet whitespaceCharacterSet] invertedSet] options:NSBackwardsSearch];
|
||||
if (range.location != NSNotFound) {
|
||||
line = [[line substringToIndex:range.location + 1] mutableCopy];
|
||||
}
|
||||
return line;
|
||||
};
|
||||
|
||||
NSMutableArray *description = [NSMutableArray arrayWithObject:self.banner];
|
||||
for (id each in self.options) {
|
||||
NSMutableString *line = [NSMutableString new];
|
||||
if ([each isKindOfClass:[BRLOption class]]) {
|
||||
BRLOption *option = each;
|
||||
[line appendString:@" "];
|
||||
if (option.flag) {
|
||||
[line appendFormat:@"-%c", option.flag];
|
||||
[line appendString:option.name ? @", " : @" "];
|
||||
} else {
|
||||
[line appendString:@" "];
|
||||
}
|
||||
if (option.name) {
|
||||
[line appendFormat:@"%@%-24s ", [self longPrefix], option.name];
|
||||
} else {
|
||||
[line appendString:@" "];
|
||||
}
|
||||
if (line.length > 37) {
|
||||
line = trimLine(line);
|
||||
[line appendString:@"\n "];
|
||||
}
|
||||
if (option.description) {
|
||||
[line appendString:option.description];
|
||||
}
|
||||
line = trimLine(line);
|
||||
} else {
|
||||
[line appendFormat:@"%@", each];
|
||||
}
|
||||
[description addObject:line];
|
||||
}
|
||||
return [[description componentsJoinedByString:@"\n"] stringByAppendingString:@"\n"];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSString *)longPrefix
|
||||
{
|
||||
return self.isLongOnly ? @"-" : @"--";
|
||||
}
|
||||
|
||||
@end
|
22
Pods/BRLOptionParser/LICENSE
generated
Normal file
22
Pods/BRLOptionParser/LICENSE
generated
Normal file
@ -0,0 +1,22 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright © 2013-2015 Stephen Celis (<stephen@stephencelis.com>)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
88
Pods/BRLOptionParser/README.markdown
generated
Normal file
88
Pods/BRLOptionParser/README.markdown
generated
Normal file
@ -0,0 +1,88 @@
|
||||
# BRLOptionParser [![Build Status][1]][2]
|
||||
|
||||
A short wrapper for [getopt_long(3)][3] (and getopt_long_only(3)).
|
||||
|
||||
[1]: https://img.shields.io/travis/stephencelis/BRLOptionParser.svg?style=flat
|
||||
[2]: https://travis-ci.org/stephencelis/BRLOptionParser
|
||||
[3]: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/getopt_long.3.html
|
||||
|
||||
## Install
|
||||
|
||||
With [CocoaPods][4]:
|
||||
|
||||
``` rb
|
||||
# Podfile
|
||||
pod 'BRLOptionParser', '~> 0.3.1'
|
||||
```
|
||||
|
||||
[4]: http://cocoapods.org
|
||||
|
||||
## Example
|
||||
|
||||
``` objc
|
||||
// main.m
|
||||
#import <BRLOptionParser/BRLOptionParser.h>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
NSString *name = @"world";
|
||||
BOOL verbose = NO;
|
||||
|
||||
BRLOptionParser *options = [BRLOptionParser new];
|
||||
|
||||
[options setBanner:@"usage: %s [-n <name>] [-vh]", argv[0]];
|
||||
[options addOption:"name" flag:'n' description:@"Your name" argument:&name];
|
||||
[options addSeparator];
|
||||
[options addOption:"verbose" flag:'v' description:nil value:&verbose];
|
||||
__weak typeof(options) weakOptions = options;
|
||||
[options addOption:"help" flag:'h' description:@"Show this message" block:^{
|
||||
printf("%s", [[weakOptions description] UTF8String]);
|
||||
exit(EXIT_SUCCESS);
|
||||
}];
|
||||
|
||||
NSError *error = nil;
|
||||
if (![options parseArgc:argc argv:argv error:&error]) {
|
||||
const char * message = error.localizedDescription.UTF8String;
|
||||
fprintf(stderr, "%s: %s\n", argv[0], message);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr, "(Preparing to say hello...)\n");
|
||||
}
|
||||
|
||||
printf("Hello, %s!\n", name.UTF8String);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
In practice:
|
||||
|
||||
```
|
||||
$ hello
|
||||
Hello, world!
|
||||
$ hello -h
|
||||
usage: hello [-n <name>] [-vh]
|
||||
-n, --name Your name
|
||||
|
||||
-v, --verbose
|
||||
-h, --help Show this message
|
||||
$ hello -n
|
||||
hello: option `-n' requires an argument
|
||||
$ hello --name Stephen
|
||||
Hello, Stephen!
|
||||
$ hello -vngoodbye
|
||||
(Preparing to say hello...)
|
||||
Hello, goodbye!
|
||||
$ hello --goodbye
|
||||
hello: unrecognized option `--goodbye'
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
BRLOptionParser is available under the MIT license. See the LICENSE file
|
||||
for more information.
|
||||
|
Reference in New Issue
Block a user